From ad4cb97286715231a116e9b1b6b09d31367c14de Mon Sep 17 00:00:00 2001 From: Vera Xia Date: Mon, 8 Apr 2024 14:11:44 -0700 Subject: [PATCH] Fix: TLS API update & unit test fix (#247) --- .../io/TLSContextOptions.swift | 19 ++++--- .../io/TLSContextTests.swift | 55 ++++++++++++------- .../FileBasedConfigurationTests.swift | 5 ++ 3 files changed, 49 insertions(+), 30 deletions(-) diff --git a/Source/AwsCommonRuntimeKit/io/TLSContextOptions.swift b/Source/AwsCommonRuntimeKit/io/TLSContextOptions.swift index bfc392de5..536861bb4 100644 --- a/Source/AwsCommonRuntimeKit/io/TLSContextOptions.swift +++ b/Source/AwsCommonRuntimeKit/io/TLSContextOptions.swift @@ -1,6 +1,7 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0. +import struct Foundation.Data import AwsCIo public class TLSContextOptions: CStruct { private var rawValue: UnsafeMutablePointer @@ -11,14 +12,14 @@ public class TLSContextOptions: CStruct { /// Initializes TLSContextOptions for mutual TLS (mTLS), with client certificate and private key in the PKCS#12 format. /// - /// NOTE: This only works on Apple devices. + /// NOTE: This only works on Apple devices. The library is currently only tested on macOS. /// /// - Parameters: /// - pkcs12Path: Path to PKCS #12 file. The file is loaded from disk and stored internally. It must remain in /// memory for the lifetime of the returned object. /// - password: Password to PKCS #12 file. It must remain in memory for the lifetime of the returned object. /// - Throws: CommonRuntimeError.crtError -#if os(macOS) +#if os(tvOS) || os(iOS) || os(watchOS) || os(macOS) public static func makeMTLS( pkcs12Path: String, password: String) throws -> TLSContextOptions { @@ -37,8 +38,8 @@ public class TLSContextOptions: CStruct { /// - Throws: CommonRuntimeError.crtError #if !(os(tvOS) || os(iOS) || os(watchOS)) public static func makeMTLS( - certificateData: String, - privateKeyData: String) throws -> TLSContextOptions { + certificateData: Data, + privateKeyData: Data) throws -> TLSContextOptions { try TLSContextOptions(certificateData: certificateData, privateKeyData: privateKeyData) } #endif @@ -78,16 +79,16 @@ public class TLSContextOptions: CStruct { } } - init(certificateData: String, - privateKeyData: String) throws { + init(certificateData: Data, + privateKeyData: Data) throws { self.rawValue = allocator.allocate(capacity: 1) - guard withOptionalByteCursorPointerFromStrings( - certificateData, privateKeyData, {certificateByteCursor, privatekeyByteCursor in + guard certificateData.withAWSByteCursorPointer({ certificateByteCursor in + return privateKeyData.withAWSByteCursorPointer { privatekeyByteCursor in return aws_tls_ctx_options_init_client_mtls(self.rawValue, allocator.rawValue, certificateByteCursor, privatekeyByteCursor) - }) == AWS_OP_SUCCESS else { + }}) == AWS_OP_SUCCESS else { throw CommonRunTimeError.crtError(CRTError.makeFromLastError()) } } diff --git a/Test/AwsCommonRuntimeKitTests/io/TLSContextTests.swift b/Test/AwsCommonRuntimeKitTests/io/TLSContextTests.swift index c928c3999..ccc77a4f1 100644 --- a/Test/AwsCommonRuntimeKitTests/io/TLSContextTests.swift +++ b/Test/AwsCommonRuntimeKitTests/io/TLSContextTests.swift @@ -5,25 +5,38 @@ import XCTest class TLSContextTests: XCBaseTestCase { - func testCreateTlsContextWithOptions() throws { - let options = TLSContextOptions() - let context = try TLSContext(options: options, mode: .client) - _ = TLSConnectionOptions(context: context) - } - -// TODO: The test is disabled as the github CI failed on access default keychain. -// TODO: Add test for testCreateTlsContextWithRawData() -// func testCreateTlsContextWithFilePath() throws{ -// try skipIfiOS() -// try skipIftvOS() -// try skipIfwatchOS() -// -// let cert_path = try getEnvironmentVarOrSkipTest(environmentVarName: "AWS_TEST_MQTT311_IOT_CORE_X509_CERT") -// let private_key_path = try getEnvironmentVarOrSkipTest(environmentVarName: "AWS_TEST_MQTT311_IOT_CORE_X509_KEY") -// -// let options = try TLSContextOptions.makeMTLS(certificatePath: cert_path, privateKeyPath: private_key_path) -// -// let context = try TLSContext(options: options, mode: .client) -// _ = TLSConnectionOptions(context: context) -// } + func testCreateTlsContextWithOptions() throws { + let options = TLSContextOptions() + let context = try TLSContext(options: options, mode: .client) + _ = TLSConnectionOptions(context: context) + } + +#if os(macOS) || os(Linux) + func testCreateTlsContextWithFilePath() 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 options = try TLSContextOptions.makeMTLS(certificatePath: certPath, privateKeyPath: privateKeyPath) + + let context = try TLSContext(options: options, mode: .client) + _ = TLSConnectionOptions(context: context) + } +#endif + +#if os(macOS) || os(Linux) + func testCreateTlsContextWithData() 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) + + let context = try TLSContext(options: options, mode: .client) + _ = TLSConnectionOptions(context: context) + } +#endif } diff --git a/Test/AwsCommonRuntimeKitTests/sdkutils/FileBasedConfigurationTests.swift b/Test/AwsCommonRuntimeKitTests/sdkutils/FileBasedConfigurationTests.swift index c8752181a..62513eaf6 100644 --- a/Test/AwsCommonRuntimeKitTests/sdkutils/FileBasedConfigurationTests.swift +++ b/Test/AwsCommonRuntimeKitTests/sdkutils/FileBasedConfigurationTests.swift @@ -67,7 +67,9 @@ class FileBasedConfigurationTests: XCBaseTestCase { func testResolveConfigPath() throws { // from $HOME let home = "/test/home" + let oldHome = getenv("HOME") setenv("HOME", home, 1) + XCTAssertEqual(try FileBasedConfiguration.resolveConfigPath(sourceType: .config), "\(home)/.aws/config") XCTAssertEqual(try FileBasedConfiguration.resolveConfigPath(sourceType: .credentials), "\(home)/.aws/credentials") @@ -84,5 +86,8 @@ class FileBasedConfigurationTests: XCBaseTestCase { // from relative path XCTAssertEqual(try FileBasedConfiguration.resolveConfigPath(sourceType: .config, overridePath: "~/.aws/config"), "\(home)/.aws/config") XCTAssertEqual(try FileBasedConfiguration.resolveConfigPath(sourceType: .credentials, overridePath: "~/.aws/credentials"), "\(home)/.aws/credentials") + + // reset home env + setenv("HOME", oldHome!, 1) } }