BlueSSLService 2.0.2

BlueSSLService 2.0.2

测试已测试
语言语言 SwiftSwift
许可证 Apache-2.0
发布上次发布2022年10月
SPM支持 SPM

Taylor FranklinBill AbtDanny SungSwift-at-IBM 维护。



  • IBM 和 Kitura 项目作者

APIDoc Build Status - Master macOS iOS Linux Apache 2 Slack Status

BlueSSLService

Swift 使用 Swift 包管理器为 BlueSocket 提供的 SSL/TLS 插件框架。在支持的 Apple 平台上工作(使用 Secure Transport)以及 Linux(使用 OpenSSL)。

先决条件

Swift

  • Swift 开源工具链 swift-5.2-RELEASE(对于最新版本,**最小要求**)
  • Swift 开源工具链 swift-5.5-RELEASE(**推荐**)
  • 包含在 版本 11.0 或更高版本的 Xcode 中的 Swift 工具链。

BlueSSLService 2.0 版本及以上支持 Swift 5.2+。对于旧版 Swift,请参阅更早版本的 BlueSSLService。

macOS

  • macOS 10.14.6(**莫贾韦**)或更高版本。
  • 使用上述工具链之一,使用版本 11.0 或更高版本的 Xcode。
  • 使用Xcode 12.5或更高版本,并使用包含的工具链(推荐)。
  • macOS提供Secure Transport。

iOS

  • iOS 10.0或更高版本
  • 使用上述工具链之一,使用版本 11.0 或更高版本的 Xcode。
  • 使用Xcode 12.5或更高版本,并使用包含的工具链(推荐)。
  • iOS提供Secure Transport。

Linux

  • Ubuntu 16.04(或16.10,但仅在16.04上进行了测试)和18.04。
  • 上述列表中的Swift开源工具链之一。
  • 发行版提供OpenSSL。 注意: 支持3.0.x和之后的OpenSSL版本。
  • 构建时需要安装相应的libssl-dev软件包。

其他平台

  • BlueSSLServicewatchOS上不受支持,因为尽管在模拟器中支持POSIX/BSD/Darwin套接字,但它们在实际设备上不受支持。
  • BlueSSLService应在tvOS上工作,但尚未进行测试。

注意: 详细信息请见Package.swift

构建

要从命令行构建SSLService

% cd <path-to-clone>
% swift build

测试

要从命令行运行提供的<口径 dni`=SSLService`单元测试

% cd <path-to-clone>
% swift build
% swift test

使用BlueSSLService

开始之前

首先您需要导入SocketSSLService框架。这可以通过以下方式完成:

import Socket
import SSLService

创建配置

客户端和服务器至少需要以下配置项:

  • CA证书(caCertificateFilecaCertificateDirPath
  • 应用证书(certificateFilePath
  • 私钥文件(keyFilePath

或者

  • 证书链文件(chainFilePath

或者,如果您使用自签名证书:

  • 应用证书(certificateFilePath
  • 私钥文件(keyFilePath

或者,若在Linux上运行(目前如此),

  • 包含PEM格式证书的字符串

或者,若在macOS上运行

  • PKCS12格式的证书链文件(chainFilePath

或者,

  • 没有证书。

BlueSSLService 提供了五种创建支持上述情况配置的方法。仅在 Apple 平台上支持最后的版本。在 Linux 上,支持所有版本。这是由于当前 Apple Secure Transport 实现强加的限制。

  • init() - 此 API 允许创建默认配置。这等同于调用下一个初始化器而不更改任何参数。
  • init(withCipherSuite cipherSuite: String? = nil, clientAllowsSelfSignedCertificates: Bool = true) - 此 API 允许创建不包含后置证书或证书链的配置。您可以选择提供cipherSuite并决定在高客户端模式下,是否允许服务器使用自签名证书。
  • init(withCACertificatePath caCertificateFilePath: String?, usingCertificateFile certificateFilePath: String?, withKeyFile keyFilePath: String? = nil, usingSelfSignedCerts selfSigned: Bool = true, cipherSuite: String? = nil) - 此 API 允许您使用包含的证书授权(Certificate Authority, CA)文件创建配置。第二个参数是用于应用建立连接的证书文件路径。下一个参数是用于与证书中的公钥对应的私钥文件的路径。如果您在使用自签名证书,将最后一个参数设置为true。
  • init(withCACertificateDirectory caCertificateDirPath: String?, usingCertificateFile certificateFilePath: String?, withKeyFile keyFilePath: String? = nil, usingSelfSignedCerts selfSigned: Bool = true, cipherSuite: String? = nil) - 此 API 允许您使用证书授权(Certificate Authority, CA)文件目录创建配置。这些 CA 证书必须是使用 OpenSSL 提供的证书工具散列的。以下参数与前一个 API 相同。
  • init(withPEMCertificateString certificateString: String, usingSelfSignedCerts selfSigned: Bool = true, cipherSuite: String? = nil) - 在提供以字符串形式表示的PEM格式证书时使用此API。 注意:目前此API仅在Linux上可用。
  • init(withChainFilePath chainFilePath: String? = nil, withPassword password: String? = nil, usingSelfSignedCerts selfSigned: Bool = true, clientAllowsSelfSignedCertificates: Bool = false, cipherSuite: String? = nil) - 此API允许您使用单个Certificate Chain File(参看以下第2点)创建配置。使用第三个参数添加可选密码(如果需要)。如果使用的证书是自签名的,则将第三个参数设置为true,否则设置为false。如果配置客户端并希望该客户端可以使用自签名证书与服务器连接,则将第四个参数设置为true。

注意1:所有CertificatePrivate Key文件必须是PEM格式。如果通过字符串提供证书,则证书必须是PEM格式。

注意2:如果使用证书链文件,证书必须是PEM格式,并且必须以主题证书(实际客户端或服务器证书)开始排序,然后是如果适用的话中间的CA证书,最后是最高级别(根)的CA

注意3:对于API的第一和第二个版本,如果您的Private key包含在您的证书文件中,您可以省略此参数,并且API将使用指定给证书文件的相同文件名。

注意4:如果您希望自定义使用的加密套件,可以在使用上述初始化方法之一时指定cipherSuite参数。如果不指定,Linux上的默认值设置为DEFAULT。在macOS上,目前不支持设置此参数,尝试设置它会导致结果不可预测。请参见下面的示例。

注意5:如果您正在macOS上运行,则必须使用最后一种形式的initConfiguration提供证书链文件,格式为PKCS12,并在需要时提供password

示例

以下示例说明了使用第一种形式的API创建配置(在Linux上)使用自签名证书文件作为密钥文件,并且没有提供证书链文件。它还说明了将加密套件设置为默认值ALL

import SSLService

...

let myCertPath = "/opt/myApp/config/myCertificate.pem"
let myKeyPath = "/opt/myApp/config/myKeyFile.pem"

let myConfig = SSLService.Configuration(withCACertificateDirectory: nil, usingCertificateFile: myCertPath, withKeyFile: myKeyFile)

myConfig.cipherSuite = "ALL"

...

注意:此示例利用了SSLService.Configuration.init函数上的可用default参数。另外,在macOS上目前不支持更改加密套件。

创建并使用SSLService

以下API用于创建SSLService

  • init?(usingConfiguration config: Configuration) throws - 这将使用先前创建的Configuration创建SSLService实例。

一旦创建了 SSLService,它可以应用于刚刚创建的 Socket 实例。这必须在使用 Socket 之前完成。以下代码片段演示了如何实现(再次使用 Linux)。注意:为了简洁,省略了异常处理。

import Socket
import SSLService

...

// Create the configuration...
let myCertPath = "/opt/myApp/config/myCertificate.pem"
let myKeyPath = "/opt/myApp/config/myKeyFile.pem"

let myConfig = SSLService.Configuration(withCACertificateDirectory: nil, usingCertificateFile: myCertPath, withKeyFile: myKeyFile)

// Create the socket...
var socket = try Socket.create()
guard let socket = socket else {
  fatalError("Could not create socket.")
}

// Create and attach the SSLService to the socket...
//  - Note: if you're going to be using the same 
//          configuration over and over, it'd be 
//          better to create it in the beginning 
//          as `let` constant.
socket.delegate = try SSLService(usingConfiguration: myConfig)

// Start listening...
try socket.listen(on: 1337)

上面的示例创建了一个 SSL 服务器 套接字。将 socket.listen 函数替换为 socket.connect 将导致创建一个如以下所示的 SSL 客户端

// Connect to the server...
try socket.connect(to: "someplace.org", port: 1337)

SSLService 处理所有数据安全传输的协商和设置。是否将 Socket 设置为服务器或客户端 Socket 的决定因素是用于发起连接的 API。调用 listen() 将将 Socket 设置为服务器套接字。调用 connect() 将导致客户端设置。

扩展连接验证

SSLService 提供了一种回调机制,以便您可以指定 附加 验证逻辑。创建 SSLService 实例后,您可以设置实例变量 verifyCallback。此实例变量具有以下签名

public var verifyCallback: ((_ service: SSLService) -> (Bool, String?))? = nil

设置此回调不是必需的。除非设置,否则默认为 nil。您的回调将接收一个参数,即具有此回调的 SSLService 实例。这将允许您访问 SSLService 实例的公共成员,以便进行附加验证。完成验证后,您的回调应返回一个元组。第一个值是一个 Bool,指示函数的成功或失败。第二个值是一个可选的 String 值,在验证失败的情况下用于提供描述。在回调失败的情况下,内部验证函数将抛出一个 exception重要提示:有效使用此回调需要了解底层安全传输服务,即 支持的苹果平台 上的 Apple Secure TransportLinux 上的 OpenSSL

跳过连接验证

如果您需要,SSLService 可以 跳过 连接验证。要完成此操作,请在创建 SSLService 实例后将属性 skipVerification 设置为 true。但是,如果设置了上面描述的 verifyCallback 属性,则会调用该回调,无论此设置如何。默认值是 false。在 production 环境中跳过连接验证是 不推荐 的,除非您通过 verificationCallback 提供了验证。

社区

我们喜欢谈论服务器端Swift和Kitura。加入我们的Slack来认识团队!

许可

此库依据Apache 2.0协议授权。完整授权文本可在LICENSE中查看。