• Stars
    star
    96
  • Rank 339,003 (Top 7 %)
  • Language
    Swift
  • License
    Apache License 2.0
  • Created almost 8 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

SSL/TLS Add-in for BlueSocket using Secure Transport and OpenSSL

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

BlueSSLService

SSL/TLS Add-in framework for BlueSocket in Swift using the Swift Package Manager. Works on supported Apple platforms (using Secure Transport) and on Linux (using OpenSSL).

Prerequisites

Swift

  • Swift Open Source swift-5.2-RELEASE toolchain (Minimum REQUIRED for latest release)
  • Swift Open Source swift-5.5-RELEASE toolchain (Recommended)
  • Swift toolchain included in Xcode Version 11.0 or higher.

BlueSSLService version 2.0 and above supports Swift 5.2+. See older versions of BlueSSLService for older versions of Swift.

macOS

  • macOS 10.14.6 (Mojave) or higher.
  • Xcode Version 11.0 or higher using one of the above toolchains.
  • Xcode Version 12.5 or higher using the included toolchain (Recommended).
  • Secure Transport is provided by macOS.

iOS

  • iOS 10.0 or higher
  • Xcode Version 11.0 or higher using one of the above toolchains.
  • Xcode Version 12.5 or higher using the included toolchain (Recommended).
  • Secure Transport is provided by iOS.

Linux

  • Ubuntu 16.04 (or 16.10 but only tested on 16.04) and 18.04.
  • One of the Swift Open Source toolchain listed above.
  • OpenSSL is provided by the distribution. Note: 3.0.x and later releases of OpenSSL are supported.
  • The appropriate libssl-dev package is required to be installed when building.

Other Platforms

  • BlueSSLService is NOT supported on watchOS since POSIX/BSD/Darwin sockets are not supported on the actual device although they are supported in the simulator.
  • BlueSSLService should work on tvOS but has NOT been tested.

Note: See Package.swift for details.

Build

To build SSLService from the command line:

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

Testing

To run the supplied unit tests for SSLService from the command line:

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

Using BlueSSLService

Before starting

The first you need to do is import both the Socket and SSLService frameworks. This is done by the following:

import Socket
import SSLService

Creating the Configuration

Both clients and server require at a minimum the following configuration items:

  • CA Certficate (either caCertificateFile or caCertificateDirPath)
  • Application certificate (certificateFilePath)
  • Private Key file (keyFilePath)

or

  • Certificate Chain File (chainFilePath)

or, if using self-signed certificates:

  • Application certificate (certificateFilePath)
  • Private Key file (keyFilePath)

or, if running on Linux (for now),

  • A string containing a PEM formatted certificate

or, if running on macOS:

  • Certificate Chain File (chainFilePath) in PKCS12 format

or,

  • No certificate at all.

BlueSSLService provides five ways to create a Configuration supporting the scenarios above. Only the last version is supported on Apple platforms. On Linux, ALL versions are supported. This is due to the limits imposed on the current implementation of Apple Secure Transport.

  • init() - This API allows for the creation of default configuration. This is equivalent to calling the next initializer without changing any parameters.
  • init(withCipherSuite cipherSuite: String? = nil, clientAllowsSelfSignedCertificates: Bool = true) - This API allows for the creation of configuration that does not contain a backing certificate or certificate chain. You can optionally provide a cipherSuite and decide whether to allow, when in client mode, use of self-signed certificates by the server.
  • init(withCACertificatePath caCertificateFilePath: String?, usingCertificateFile certificateFilePath: String?, withKeyFile keyFilePath: String? = nil, usingSelfSignedCerts selfSigned: Bool = true, cipherSuite: String? = nil) - This API allows you to create a configuration using a self contained Certificate Authority (CA) file. The second parameter is the path to the Certificate file to be used by application to establish the connection. The next parameter is the path to the Private Key file used by application corresponding to the Public Key in the Certificate. If you're using self-signed certificates, set the last parameter to true.
  • init(withCACertificateDirectory caCertificateDirPath: String?, usingCertificateFile certificateFilePath: String?, withKeyFile keyFilePath: String? = nil, usingSelfSignedCerts selfSigned: Bool = true, cipherSuite: String? = nil) - This API allows you to create a configuration using a directory of Certificate Authority (CA) files. These CA certificates must be hashed using the Certificate Tool provided by OpenSSL. The following parameters are identical to the previous API.
  • init(withPEMCertificateString certificateString: String, usingSelfSignedCerts selfSigned: Bool = true, cipherSuite: String? = nil) - This API used when supplying a PEM formatted certificate presented as a String. NOTE: At present, this API is only available on Linux.
  • init(withChainFilePath chainFilePath: String? = nil, withPassword password: String? = nil, usingSelfSignedCerts selfSigned: Bool = true, clientAllowsSelfSignedCertificates: Bool = false, cipherSuite: String? = nil) - This API allows you to create a configuration using a single Certificate Chain File (see note 2 below). Add an optional password (if required) using the third parameter. Set the third parameter to true if the certificates you are using are self-signed, otherwise set it to false. If configuring a client and you want that client to be able to connect to servers using self-signed certificates, set the fourth parameter to true.

Note 1: All Certificate and Private Key files must be PEM format. If supplying a certificate via a String, it must be PEM formatted.

Note 2: If using a certificate chain file, the certificates must be in PEM format and must be sorted starting with the subject's certificate (actual client or server certificate), followed by intermediate CA certificates if applicable, and ending at the highest level (root) CA.

Note 3: For the first two versions of the API, if your Private key is included in your certificate file, you can omit this parameter and the API will use the same file name as specified for the certificate file.

Note 4: If you desire to customize the cipher suite used, you can do so by specifying the cipherSuite parameter when using one of the above initializers. If not specified, the default value is set to DEFAULT on Linux. On macOS, setting of this parameter is currently not supported and attempting to set it will result in unpredictable results. See the example below.

Note 5: If you're running on macOS, you must use the last form of init for the Configuration and provide a certificate chain file in PKCS12 format, supplying a password if needed.

Example

The following illustrates creating a configuration (on Linux) using the second form of the API above using a self-signed certificate file as the key file and not supplying a certificate chain file. It also illustrates setting the cipher suite to ALL from the default:

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"

...

Note: This example takes advantage of the default parameters available on the SSLService.Configuration.init function. Also, changing of the cipher suite on macOS is currently not supported.

Creating and using the SSLService

The following API is used to create the SSLService:

  • init?(usingConfiguration config: Configuration) throws - This will create an instance of the SSLService using a previously created Configuration.

Once the SSLService is created, it can applied to a previously created Socket instance that's just been created. This needs to be done before using the Socket. The following code snippet illustrates how to do this (again using Linux). Note: Exception handling omitted for brevity.

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)

The example above creates a SSL server socket. Replacing the socket.listen function with a socket.connect would result in an SSL client being created as illustrated below:

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

SSLService handles all the negotiation and setup for the secure transfer of data. The determining factor for whether or not a Socket is setup as a server or client Socket is API which is used to initiate a connection. listen() will cause the Socket to be setup as a server socket. Calling connect() results a client setup.

Extending Connection Verification

SSLService provides a callback mechanism should you need to specify additional verification logic. After creating the instance of SSLService, you can set the instance variable verifyCallback. This instance variable has the following signature:

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

Setting this callback is not required. It defaults to nil unless set. The first parameter passed to your callback is the instance of SSLService that has this callback. This will allow you to access the public members of the SSLService instance in order to do additional verification. Upon completion, your callback should return a tuple. The first value is a Bool indicating the sucess or failure of the routine. The second value is an optional String value used to provide a description in the case where verification failed. In the event of callback failure, an exception will be thrown by the internal verification function. Important Note: To effectively use this callback requires knowledge of the platforms underlying secure transport service, Apple Secure Transport on supported Apple platforms and OpenSSL on Linux.

Skipping Connection Verification

If desired, SSLService can skip the connection verification. To accomplish this, set the property skipVerification to true after creating the SSLService instance. However, if the verifyCallback property (described above) is set, that callback will be called regardless of this setting. The default for property is false. It is NOT recommended that you skip the connection verification in a production environment unless you are providing verification via the verificationCallback.

Community

We love to talk server-side Swift and Kitura. Join our Slack to meet the team!

License

This library is licensed under Apache 2.0. Full license text is available in LICENSE.

More Repositories

1

Kitura

A Swift web framework and HTTP server.
Swift
7,614
star
2

BlueSocket

Socket framework for Swift using the Swift Package Manager. Works on iOS, macOS, and Linux.
Swift
1,392
star
3

Swift-JWT

JSON Web Tokens in Swift
Swift
539
star
4

Swift-Kuery

SQL database abstraction layer
Swift
427
star
5

Swift-SMTP

Swift SMTP client
Swift
249
star
6

Swift-Kuery-ORM

An ORM for Swift, built on Codable
Swift
211
star
7

BlueCryptor

Swift cross-platform crypto library using CommonCrypto/libcrypto
Swift
189
star
8

HeliumLogger

A lightweight logging framework for Swift
Swift
175
star
9

swift-html-entities

HTML5 spec-compliant character encoder/decoder for Swift
Swift
165
star
10

swift-ubuntu-docker

🚫 This repo is deprecated - please use the images here: https://hub.docker.com/_/swift
Vim Script
155
star
11

BlueRSA

RSA public/private key encryption, private key signing and public key verification in Swift using the Swift Package Manager. Works on iOS, macOS, and Linux (work in progress).
Swift
128
star
12

SwiftyRequest

SwiftyRequest is an HTTP networking library built for Swift.
Swift
108
star
13

Kitura-net

Kitura networking
Swift
103
star
14

Kitura-redis

Swift Redis library
Swift
94
star
15

BlueECC

Elliptic-curve cryptography for Swift
Swift
92
star
16

BlueSignals

Generic Cross Platform Signal Handler
Swift
92
star
17

Kitura-Sample

A sample application that shows how to use various features of Kitura
Swift
80
star
18

Configuration

Hierarchical configuration manager for Swift applications
Swift
78
star
19

Kitura-WebSocket

WebSocket support for Kitura
Swift
66
star
20

Swift-Kuery-PostgreSQL

PostgreSQL plugin for Swift-Kuery framework
Swift
61
star
21

OpenSSL

Swift modulemaps for libSSL and libcrypto
C
58
star
22

SwiftKafka

Swift SDK for Apache Kafka
Swift
58
star
23

KituraKit

Swift client library for using Codable routes with Kitura
Swift
58
star
24

Kitura-CouchDB

CouchDB adapter for Kitura
Swift
50
star
25

CircuitBreaker

A Swift Circuit Breaker library – Improves application stability and reliability.
Swift
45
star
26

Kitura-Credentials

A pluggable framework for validating user credentials in a Swift server using Kitura
Swift
40
star
27

Kitura-NIO

A networking library for Kitura, based on SwiftNIO
Swift
37
star
28

Kitura-OpenAPI

OpenAPI support for Kitura
Swift
36
star
29

TypeDecoder

A Swift library to allow the runtime inspection of Swift language native and complex types.
Swift
35
star
30

SwiftKueryMySQL

MySQL plugin for Swift-Kuery framework
Swift
34
star
31

Package-Builder

Build and utility scripts used for continuous integration builds for Swift Package Manager projects on the Travis CI environment
Shell
33
star
32

CCurl

Modulemap for the libcurl library
Objective-C
30
star
33

Kitura-StencilTemplateEngine

Stencil templating for Kitura
Swift
26
star
34

kitura.dev

http://www.kitura.dev
JavaScript
26
star
35

LoggerAPI

Logger protocol
Swift
25
star
36

Kitura-Markdown

Templating engine for Kitura that uses Markdown based templates
C
24
star
37

Health

An application health library for Swift.
Swift
21
star
38

Kitura-Session

A pluggable framework for managing user sessions in a Swift server using Kitura
Swift
18
star
39

Kitura-WebSocket-NIO

A SwiftNIO based implementation of WebSocket for Kitura
Swift
17
star
40

CommonCrypto

CommonCrypto Module Map
Swift
17
star
41

FileKit

Swift
16
star
42

Swift-Kuery-SQLite

An SQLite plugin for the Swift-Kuery framework
Swift
16
star
43

Kitura-TemplateEngine

Kitura Template Engine protocol
Swift
15
star
44

Kitura-CredentialsHTTP

A plugin for the Kitura-Credentials framework that authenticates using HTTP Basic and Digest authentication
Swift
15
star
45

kitura-cli

⌨️ Kitura command-line interface
Go
13
star
46

KituraContracts

A library containing type definitions shared by client and server Kitura code.
Swift
12
star
47

CZlib

Module map for Zlib library
Swift
11
star
48

CloudEnvironment

Convenience Swift package for accessing environment variables, credentials.
Swift
11
star
49

Kitura-CredentialsFacebook

A plugin for the Kitura-Credentials framework that authenticates using the Facebook web login
Swift
9
star
50

Kitura-CORS

Kitura CORS middleware
Swift
9
star
51

Kitura-Cache

Kitura cache
Swift
9
star
52

Kitura-CredentialsGoogle

A plugin for the Kitura-Credentials framework that authenticates using the Google web login
Swift
8
star
53

Swift-cfenv

Easy access to Cloud Foundry application environment for Swift Packages.
Swift
8
star
54

Kitura-Compression

Kitura compression middleware
Swift
6
star
55

CEpoll

A modulemap file and include to help Swift code use epoll on Linux
Swift
5
star
56

Kitura-WebSocket-Client

A WebSocket client based on SwiftNIO
Swift
5
star
57

Kitura-CredentialsGitHub

A plugin for the Kitura-Credentials framework that authenticates using the GitHub web login
Swift
4
star
58

Kitura-MustacheTemplateEngine

Adapter of GRMustache Template Engine to Kitura Template Engine
Swift
4
star
59

CHTTPParser

Modulemap for the http-parser library
C
4
star
60

Kitura-WebSocket-Compression

A WebSocket compression library based on SwiftNIO
Swift
3
star
61

Kitura-Session-Redis

Kitura-Session store using Redis as the backing store
Swift
3
star
62

generator-swiftserver-projects

Autogenerated Kitura projects
Shell
2
star
63

Kitura-CredentialsJWT

A plugin for the Kitura-Credentials framework that supports JWT authentication.
Swift
2
star
64

homebrew-kitura

Homebrew tap
Ruby
2
star
65

Kitura-Benchmarks

Benchmarks for Kitura
Swift
2
star
66

anapistula

Simple standalone web server in swift
Swift
1
star
67

CLibpq

PostgreSQL wrapper
Swift
1
star
68

ShellToolKit

Utility classes to help with common system/shell actions in Swift
Swift
1
star