-
Notifications
You must be signed in to change notification settings - Fork 122
/
Copy pathTLSConfiguration.swift
144 lines (124 loc) · 5.33 KB
/
TLSConfiguration.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
//===----------------------------------------------------------------------===//
//
// This source file is part of the AsyncHTTPClient open source project
//
// Copyright (c) 2020 Apple Inc. and the AsyncHTTPClient project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of AsyncHTTPClient project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//
#if canImport(Network)
import Foundation
import Network
import NIOSSL
import NIOTransportServices
extension TLSVersion {
/// return Network framework TLS protocol version
var nwTLSProtocolVersion: tls_protocol_version_t {
switch self {
case .tlsv1:
return .TLSv10
case .tlsv11:
return .TLSv11
case .tlsv12:
return .TLSv12
case .tlsv13:
return .TLSv13
}
}
}
extension TLSVersion {
/// return as SSL protocol
var sslProtocol: SSLProtocol {
switch self {
case .tlsv1:
return .tlsProtocol1
case .tlsv11:
return .tlsProtocol11
case .tlsv12:
return .tlsProtocol12
case .tlsv13:
return .tlsProtocol13
}
}
}
@available(macOS 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *)
extension TLSConfiguration {
/// Dispatch queue used by Network framework TLS to control certificate verification
static var tlsDispatchQueue = DispatchQueue(label: "TLSDispatch")
/// create NWProtocolTLS.Options for use with NIOTransportServices from the NIOSSL TLSConfiguration
///
/// - Parameter queue: Dispatch queue to run `sec_protocol_options_set_verify_block` on.
/// - Returns: Equivalent NWProtocolTLS Options
func getNWProtocolTLSOptions() -> NWProtocolTLS.Options {
let options = NWProtocolTLS.Options()
// minimum TLS protocol
if #available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, macCatalyst 13.0, *) {
sec_protocol_options_set_min_tls_protocol_version(options.securityProtocolOptions, self.minimumTLSVersion.nwTLSProtocolVersion)
} else {
#if !targetEnvironment(macCatalyst)
sec_protocol_options_set_tls_min_version(options.securityProtocolOptions, self.minimumTLSVersion.sslProtocol)
#endif
}
// maximum TLS protocol
if let maximumTLSVersion = self.maximumTLSVersion {
if #available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, macCatalyst 13.0, *) {
sec_protocol_options_set_max_tls_protocol_version(options.securityProtocolOptions, maximumTLSVersion.nwTLSProtocolVersion)
} else {
#if !targetEnvironment(macCatalyst)
sec_protocol_options_set_tls_max_version(options.securityProtocolOptions, maximumTLSVersion.sslProtocol)
#endif
}
}
// application protocols
for applicationProtocol in self.applicationProtocols {
applicationProtocol.withCString { buffer in
sec_protocol_options_add_tls_application_protocol(options.securityProtocolOptions, buffer)
}
}
// the certificate chain
if self.certificateChain.count > 0 {
preconditionFailure("TLSConfiguration.certificateChain is not supported")
}
// cipher suites
if self.cipherSuites.count > 0 {
// TODO: Requires NIOSSL to provide list of cipher values before we can continue
// https://github.com/apple/swift-nio-ssl/issues/207
}
// key log callback
if self.keyLogCallback != nil {
preconditionFailure("TLSConfiguration.keyLogCallback is not supported")
}
// private key
if self.privateKey != nil {
preconditionFailure("TLSConfiguration.privateKey is not supported")
}
// renegotiation support key is unsupported
// trust roots
if let trustRoots = self.trustRoots {
guard case .default = trustRoots else {
preconditionFailure("TLSConfiguration.trustRoots != .default is not supported")
}
}
switch self.certificateVerification {
case .none:
// add verify block to control certificate verification
sec_protocol_options_set_verify_block(
options.securityProtocolOptions,
{ _, _, sec_protocol_verify_complete in
sec_protocol_verify_complete(true)
}, TLSConfiguration.tlsDispatchQueue
)
case .noHostnameVerification:
precondition(self.certificateVerification != .noHostnameVerification, "TLSConfiguration.certificateVerification = .noHostnameVerification is not supported")
case .fullVerification:
break
}
return options
}
}
#endif