Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add TLS support #288

Draft
wants to merge 27 commits into
base: mqtt_test_app
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
aad4d76
allow tls
sbSteveK Oct 1, 2024
8a7f52a
Merge branch 'mqtt_test_app' into secitem_bindings
sbSteveK Oct 1, 2024
f248f53
add setting of secitem options
sbSteveK Oct 2, 2024
0406905
aws-c-io nw_secitem branch
sbSteveK Oct 2, 2024
d261d8a
latest aws-c-io nw_secitem
sbSteveK Oct 2, 2024
08308e8
update aws-c-io
sbSteveK Oct 2, 2024
54ff235
use AWS_USE_SECITEM define
sbSteveK Oct 2, 2024
e19519a
add eventloop types to other platforms
sbSteveK Oct 2, 2024
b338b5d
lint error and differetiate between macOS and iOS/tvOS
sbSteveK Oct 2, 2024
9c2ba7f
add missing endif
sbSteveK Oct 2, 2024
827c071
try excluding dispatch queue related source files
sbSteveK Oct 2, 2024
e0dfcad
CRT changes
sbSteveK Oct 3, 2024
b507465
aws-c-io changes
sbSteveK Oct 3, 2024
a50380c
update aws-c-io changes
sbSteveK Oct 3, 2024
fb1b501
remove test error
sbSteveK Oct 3, 2024
1f3cee0
latest submodules
sbSteveK Oct 3, 2024
81946d3
update aws-c-io
sbSteveK Oct 4, 2024
78e5ac9
use latest aws-c-io
sbSteveK Oct 4, 2024
b9a6ed2
add defines in package.Swift
sbSteveK Oct 4, 2024
b2b21d1
latest aws-c-io
sbSteveK Oct 7, 2024
e6a9506
add defines to test and secitem options test
sbSteveK Oct 7, 2024
610e716
defines for swift test target
sbSteveK Oct 7, 2024
06451a0
add defines to tests in swift
sbSteveK Oct 7, 2024
9b177d2
remove watchOS testing
sbSteveK Oct 7, 2024
97ed422
pull latest aws-c-io changes
sbSteveK Oct 7, 2024
9a50b8d
update aws-c-io again
sbSteveK Oct 7, 2024
5e5bf33
update aws-c-io
sbSteveK Oct 16, 2024
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
10 changes: 2 additions & 8 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ jobs:
strategy:
fail-fast: false
matrix:
# This matrix runs tests on iOS, tvOS & watchOS, on oldest & newest supported Xcodes
# This matrix runs tests on iOS and tvOS on oldest & newest supported Xcodes
runner:
- macos-12 # x64
- macos-13 # x64
Expand All @@ -81,9 +81,7 @@ jobs:
[{ os: ios, destination: 'iOS Simulator,OS=16.1,name=iPhone 14'},
{ os: ios, destination: 'iOS Simulator,OS=17.2,name=iPhone 15'},
{ os: tvos, destination: 'tvOS Simulator,OS=16.1,name=Apple TV 4K (3rd generation) (at 1080p)'},
{ os: tvos, destination: 'tvOS Simulator,OS=17.2,name=Apple TV 4K (3rd generation) (at 1080p)'},
{ os: watchos, destination: 'watchOS Simulator,OS=10.2,name=Apple Watch SE (40mm) (2nd generation)'},
{ os: watchos, destination: 'watchOS Simulator,OS=9.1,name=Apple Watch Series 5 (40mm)'}]
{ os: tvos, destination: 'tvOS Simulator,OS=17.2,name=Apple TV 4K (3rd generation) (at 1080p)'}]
xcode:
- Xcode_14.1
- Xcode_15.2
Expand All @@ -110,10 +108,6 @@ jobs:
xcode: Xcode_14.1
- target: { os: ios, destination: 'iOS Simulator,OS=17.2,name=iPhone 15'}
xcode: Xcode_14.1
- target: { os: watchos, destination: 'watchOS Simulator,OS=10.2,name=Apple Watch SE (40mm) (2nd generation)'}
xcode: Xcode_14.1
- target: { os: watchos, destination: 'watchOS Simulator,OS=9.1,name=Apple Watch Series 5 (40mm)'}
xcode: Xcode_15.2
steps:
- name: Build ${{ env.PACKAGE_NAME }} + consumers
run: |
Expand Down
18 changes: 17 additions & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ let cSettings: [CSetting] = [
.define("AWS_APPSTORE_SAFE"),
]

/// Store any defines that will be used by Swift Tests in swiftTestSettings
var swiftTestSettings: [SwiftSetting] = []

//////////////////////////////////////////////////////////////////////
/// Configure C targets.
/// Note: We can not use unsafe flags because SwiftPM makes the target ineligible for use by other packages.
Expand Down Expand Up @@ -124,14 +127,26 @@ awsCIoPlatformExcludes.append("source/posix")
awsCIoPlatformExcludes.append("source/linux")
awsCIoPlatformExcludes.append("source/s2n")
awsCIoPlatformExcludes.append("source/darwin")
cSettingsIO.append(.define("AWS_USE_IO_COMPLETION_PORTS"))
swiftTestSettings.append(.define("AWS_USE_IO_COMPLETION_PORTS"))
#elseif os(Linux)
awsCIoPlatformExcludes.append("source/windows")
awsCIoPlatformExcludes.append("source/bsd")
awsCIoPlatformExcludes.append("source/darwin")
cSettingsIO.append(.define("AWS_USE_EPOLL"))
swiftTestSettings.append(.define("AWS_USE_EPOLL"))
#else // macOS, iOS, watchOS, tvOS
awsCIoPlatformExcludes.append("source/windows")
awsCIoPlatformExcludes.append("source/linux")
awsCIoPlatformExcludes.append("source/s2n")
cSettingsIO.append(.define("__APPLE__"))
cSettingsIO.append(.define("AWS_USE_DISPATCH_QUEUE", .when(platforms: [.iOS, .tvOS])))
cSettingsIO.append(.define("AWS_USE_SECITEM", .when(platforms: [.iOS, .tvOS])))
cSettingsIO.append(.define("AWS_USE_KQUEUE", .when(platforms: [.macOS])))
swiftTestSettings.append(.define("__APPLE__"))
swiftTestSettings.append(.define("AWS_USE_DISPATCH_QUEUE", .when(platforms: [.iOS, .tvOS])))
swiftTestSettings.append(.define("AWS_USE_SECITEM", .when(platforms: [.iOS, .tvOS])))
swiftTestSettings.append(.define("AWS_USE_KQUEUE", .when(platforms: [.macOS])))
#endif

//////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -304,7 +319,8 @@ packageTargets.append(contentsOf: [
path: "Test/AwsCommonRuntimeKitTests",
resources: [
.process("Resources")
]
],
swiftSettings: swiftTestSettings
),
.executableTarget(
name: "Elasticurl",
Expand Down
20 changes: 18 additions & 2 deletions Source/AwsCommonRuntimeKit/io/TLSContextOptions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public class TLSContextOptions: CStruct {
public static func makeMTLS(
certificateData: Data,
privateKeyData: Data) throws -> TLSContextOptions {
#if os(tvOS) || os(iOS) || os(watchOS)
#if os(watchOS)
throw CommonRunTimeError.crtError(CRTError(code: AWS_ERROR_PLATFORM_NOT_SUPPORTED.rawValue))
#endif
return try TLSContextOptions(certificateData: certificateData, privateKeyData: privateKeyData)
Expand All @@ -55,7 +55,7 @@ public class TLSContextOptions: CStruct {
public static func makeMTLS(
certificatePath: String,
privateKeyPath: String) throws -> TLSContextOptions {
#if os(tvOS) || os(iOS) || os(watchOS)
#if os(watchOS)
throw CommonRunTimeError.crtError(CRTError(code: AWS_ERROR_PLATFORM_NOT_SUPPORTED.rawValue))
#endif
return try TLSContextOptions(certificatePath: certificatePath, privateKeyPath: privateKeyPath)
Expand Down Expand Up @@ -126,6 +126,22 @@ public class TLSContextOptions: CStruct {
public func setMinimumTLSVersion(_ tlsVersion: TLSVersion) {
aws_tls_ctx_options_set_minimum_tls_version(rawValue, aws_tls_versions(rawValue: tlsVersion.rawValue))
}

/// Updates TLSContextOptions to use specified options when importing certificate and key into keychain.
///
/// NOTE: This only works on Apple devices using Apple keychain via Secitem.. The library is currently only tested on iOS.
///
/// - Parameters:
/// - certLabel: Human readable label to apply to certificate being imported into keychain.
/// - keyLabel: Human readable label to apply to key being imported into keychain.
/// - Throws: CommonRuntimeError.crtError
public func setSecitemLabels(certLabel: String? = nil, keyLabel: String? = nil) throws {
let secitemOptions = TLSSecitemOptions(certLabel: certLabel, keyLabel: keyLabel)

if aws_tls_ctx_options_set_secitem_options(rawValue, secitemOptions.rawValue) != AWS_OP_SUCCESS {
throw CommonRunTimeError.crtError(CRTError.makeFromLastError())
}
}

typealias RawType = aws_tls_ctx_options
func withCStruct<Result>(_ body: (aws_tls_ctx_options) -> Result) -> Result {
Expand Down
37 changes: 37 additions & 0 deletions Source/AwsCommonRuntimeKit/io/TLSSecitemOptions.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0.

import AwsCIo

public class TLSSecitemOptions: CStruct {
var rawValue: UnsafeMutablePointer<aws_secitem_options>

public init(
certLabel: String? = nil,
keyLabel: String? = nil) {

self.rawValue = allocator.allocate(capacity: 1)

self.rawValue.pointee.cert_label = certLabel?.withByteCursorPointer { certLabelCursorPointer in
aws_string_new_from_cursor(
allocator.rawValue,
certLabelCursorPointer)
}

self.rawValue.pointee.key_label = keyLabel?.withByteCursorPointer { keyLabelCursorPointer in
aws_string_new_from_cursor(
allocator.rawValue,
keyLabelCursorPointer)
}
}

typealias RawType = aws_secitem_options
func withCStruct<Result>(_ body: (aws_secitem_options) -> Result) -> Result {
return body(rawValue.pointee)
}

deinit {
aws_tls_secitem_options_clean_up(rawValue)
allocator.release(rawValue)
}
}
16 changes: 16 additions & 0 deletions Test/AwsCommonRuntimeKitTests/io/TLSContextTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,20 @@ class TLSContextTests: XCBaseTestCase {
_ = TLSConnectionOptions(context: context)
}
#endif

#if AWS_USE_SECITEM
func testCreateTlsContextWithSecitemOptions() throws {
let certPath = try getEnvironmentVarOrSkipTest(environmentVarName: "AWS_TEST_MQTT311_IOT_CORE_X509_CERT")
let privateKeyPath = try getEnvironmentVarOrSkipTest(environmentVarName: "AWS_TEST_MQTT311_IOT_CORE_X509_KEY")

let certificateData = try Data(contentsOf: URL(fileURLWithPath: certPath))
let privateKeyData = try Data(contentsOf: URL(fileURLWithPath: privateKeyPath))

let options = try TLSContextOptions.makeMTLS(certificateData: certificateData, privateKeyData: privateKeyData)
try options.setSecitemLabels(certLabel: "TEST_CERT_LABEL", keyLabel: "TEST_KEY_LABEL")

let context = try TLSContext(options:options, mode: .client)
_ = TLSConnectionOptions(context: context)
}
#endif
}
Loading