From 955f3ace098588cc3b9bfb430cc2488b00d49bd6 Mon Sep 17 00:00:00 2001 From: mironal Date: Sun, 10 Apr 2022 15:14:10 +0900 Subject: [PATCH 1/6] CommonCrypto/Crypto --- Sources/TwitterAPIKit/Extensions/Data.swift | 25 ------------ Sources/TwitterAPIKit/Extensions/HMAC.swift | 44 +++++++++++++++++++++ Sources/TwitterAPIKit/OAuthHelper.swift | 3 +- 3 files changed, 45 insertions(+), 27 deletions(-) create mode 100644 Sources/TwitterAPIKit/Extensions/HMAC.swift diff --git a/Sources/TwitterAPIKit/Extensions/Data.swift b/Sources/TwitterAPIKit/Extensions/Data.swift index 1a966942..8366fa36 100644 --- a/Sources/TwitterAPIKit/Extensions/Data.swift +++ b/Sources/TwitterAPIKit/Extensions/Data.swift @@ -1,31 +1,6 @@ -import CommonCrypto import Foundation extension Data { - func hmac(key: Data) -> Data { - - // Thanks: https://github.com/jernejstrasner/SwiftCrypto - - let digestLen = Int(CC_SHA1_DIGEST_LENGTH) - return withUnsafeBytes { bytes -> Data in - let result = UnsafeMutablePointer.allocate(capacity: digestLen) - defer { - result.deallocate() - } - - key.withUnsafeBytes { body in - CCHmac( - CCHmacAlgorithm(kCCHmacAlgSHA1), - body.baseAddress, - key.count, bytes.baseAddress, - count, - result - ) - } - - return Data(bytes: result, count: digestLen) - } - } func split(separator: Data, omittingEmptySubsequences: Bool = true) -> [Data] { var current = startIndex diff --git a/Sources/TwitterAPIKit/Extensions/HMAC.swift b/Sources/TwitterAPIKit/Extensions/HMAC.swift new file mode 100644 index 00000000..19c71752 --- /dev/null +++ b/Sources/TwitterAPIKit/Extensions/HMAC.swift @@ -0,0 +1,44 @@ +import Foundation + +#if canImport(CommonCrypto) + import CommonCrypto + + extension Data { + func hmac(key: Data) -> Data { + + // Thanks: https://github.com/jernejstrasner/SwiftCrypto + + let digestLen = Int(CC_SHA1_DIGEST_LENGTH) + return withUnsafeBytes { bytes -> Data in + let result = UnsafeMutablePointer.allocate(capacity: digestLen) + defer { + result.deallocate() + } + + key.withUnsafeBytes { body in + CCHmac( + CCHmacAlgorithm(kCCHmacAlgSHA1), + body.baseAddress, + key.count, bytes.baseAddress, + count, + result + ) + } + + return Data(bytes: result, count: digestLen) + } + } + } + + func createHMACSHA1(key: Data, message: Data) -> Data { + return message.hmac(key: key) + } + +#elseif canImport(Crypto) + func createHMACSHA1(key: Data, message: Data) -> Data { + // TODO + return Data() + } +#else + #error("Crypto is not available in this environment.") +#endif diff --git a/Sources/TwitterAPIKit/OAuthHelper.swift b/Sources/TwitterAPIKit/OAuthHelper.swift index 1830750f..669ec119 100644 --- a/Sources/TwitterAPIKit/OAuthHelper.swift +++ b/Sources/TwitterAPIKit/OAuthHelper.swift @@ -1,4 +1,3 @@ -import CommonCrypto import Foundation private let oauthVersion = "1.0" @@ -69,6 +68,6 @@ private func oauthSignature( let key = signingKey.data(using: .utf8)! let msg = signatureBaseString.data(using: .utf8)! - let sha1 = msg.hmac(key: key) + let sha1 = createHMACSHA1(key: key, message: msg) return sha1.base64EncodedString(options: []) } From 7c29df041139a40f6d0ad53c67dab03ea22c1a3d Mon Sep 17 00:00:00 2001 From: mironal Date: Sun, 10 Apr 2022 16:15:24 +0900 Subject: [PATCH 2/6] add swift-crypto --- Package.swift | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/Package.swift b/Package.swift index 8affa273..31d83169 100644 --- a/Package.swift +++ b/Package.swift @@ -3,6 +3,15 @@ import PackageDescription + +#if canImport(CommonCrypto) +let dependencies: [Package.Dependency] = [] +let tDependencies: [Target.Dependency] = [] +#else +let dependencies: [Package.Dependency] = [.package(url: "https://github.com/apple/swift-crypto.git", from: "2.0.0")] +let tDependencies: [Target.Dependency] = [.product(name: "Crypto", package: "swift-crypto")] +#endif + let package = Package( name: "TwitterAPIKit", platforms: [ @@ -17,16 +26,13 @@ let package = Package( name: "TwitterAPIKit", targets: ["TwitterAPIKit"]), ], - dependencies: [ - // Dependencies declare other packages that this package depends on. - // .package(url: /* package url */, from: "1.0.0"), - ], + dependencies: dependencies, targets: [ // Targets are the basic building blocks of a package. A target can define a module or a test suite. // Targets can depend on other targets in this package, and on products in packages this package depends on. .target( name: "TwitterAPIKit", - dependencies: []), + dependencies: tDependencies), .testTarget( name: "TwitterAPIKitTests", dependencies: ["TwitterAPIKit"]), From b82e73f1f73a54773d53756e686371ee507995ad Mon Sep 17 00:00:00 2001 From: mironal Date: Sun, 10 Apr 2022 16:15:48 +0900 Subject: [PATCH 3/6] fix compile error --- Sources/TwitterAPIKit/TwitterAPIKit.swift | 4 ++++ Sources/TwitterAPIKit/TwitterAPIResponse.swift | 10 +++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/Sources/TwitterAPIKit/TwitterAPIKit.swift b/Sources/TwitterAPIKit/TwitterAPIKit.swift index 0d098251..5a691576 100644 --- a/Sources/TwitterAPIKit/TwitterAPIKit.swift +++ b/Sources/TwitterAPIKit/TwitterAPIKit.swift @@ -1,5 +1,9 @@ import Foundation +#if canImport(FoundationNetworking) + @_exported import FoundationNetworking +#endif + public enum TwitterAuthenticationMethod { case none case oauth( diff --git a/Sources/TwitterAPIKit/TwitterAPIResponse.swift b/Sources/TwitterAPIKit/TwitterAPIResponse.swift index d5611018..511c1b81 100644 --- a/Sources/TwitterAPIKit/TwitterAPIResponse.swift +++ b/Sources/TwitterAPIKit/TwitterAPIResponse.swift @@ -143,8 +143,12 @@ extension String { } fileprivate var unescapingUnicodeCharacters: String { - let mutableString = NSMutableString(string: self) - CFStringTransform(mutableString, nil, "Any-Hex/Java" as NSString, true) - return mutableString as String + #if os(Linux) + return self + #else + let mutableString = NSMutableString(string: self) + CFStringTransform(mutableString, nil, "Any-Hex/Java" as NSString, true) + return mutableString as String + #endif } } From a9fc9c10e9b86ddee6aa3100045dbd0c8ceb3af3 Mon Sep 17 00:00:00 2001 From: mironal Date: Mon, 11 Apr 2022 09:07:27 +0900 Subject: [PATCH 4/6] Crypto hmac --- Package.swift | 1 - Sources/TwitterAPIKit/Extensions/HMAC.swift | 6 +++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/Package.swift b/Package.swift index 31d83169..9bd87c9b 100644 --- a/Package.swift +++ b/Package.swift @@ -3,7 +3,6 @@ import PackageDescription - #if canImport(CommonCrypto) let dependencies: [Package.Dependency] = [] let tDependencies: [Target.Dependency] = [] diff --git a/Sources/TwitterAPIKit/Extensions/HMAC.swift b/Sources/TwitterAPIKit/Extensions/HMAC.swift index 19c71752..a461dd32 100644 --- a/Sources/TwitterAPIKit/Extensions/HMAC.swift +++ b/Sources/TwitterAPIKit/Extensions/HMAC.swift @@ -4,7 +4,7 @@ import Foundation import CommonCrypto extension Data { - func hmac(key: Data) -> Data { + fileprivate func hmac(key: Data) -> Data { // Thanks: https://github.com/jernejstrasner/SwiftCrypto @@ -35,9 +35,9 @@ import Foundation } #elseif canImport(Crypto) + import Crypto func createHMACSHA1(key: Data, message: Data) -> Data { - // TODO - return Data() + return Data(HMAC.authenticationCode(for: message, using: SymmetricKey(data: key))) } #else #error("Crypto is not available in this environment.") From 79d4d8663978a5d7272cebdf8659008207303451 Mon Sep 17 00:00:00 2001 From: mironal Date: Mon, 11 Apr 2022 09:10:00 +0900 Subject: [PATCH 5/6] add comment --- Package.swift | 5 ++++- Sources/TwitterAPIKit/Extensions/HMAC.swift | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Package.swift b/Package.swift index 9bd87c9b..d3a76056 100644 --- a/Package.swift +++ b/Package.swift @@ -3,10 +3,13 @@ import PackageDescription +// Currently, CommonCrypto and CryptoKit are not available under Linux. +// If CommonCrypto is not available, swift-crypto should be used. + #if canImport(CommonCrypto) let dependencies: [Package.Dependency] = [] let tDependencies: [Target.Dependency] = [] -#else +#else // for Linux let dependencies: [Package.Dependency] = [.package(url: "https://github.com/apple/swift-crypto.git", from: "2.0.0")] let tDependencies: [Target.Dependency] = [.product(name: "Crypto", package: "swift-crypto")] #endif diff --git a/Sources/TwitterAPIKit/Extensions/HMAC.swift b/Sources/TwitterAPIKit/Extensions/HMAC.swift index a461dd32..fa2ab416 100644 --- a/Sources/TwitterAPIKit/Extensions/HMAC.swift +++ b/Sources/TwitterAPIKit/Extensions/HMAC.swift @@ -34,7 +34,7 @@ import Foundation return message.hmac(key: key) } -#elseif canImport(Crypto) +#elseif canImport(Crypto) // for Linux import Crypto func createHMACSHA1(key: Data, message: Data) -> Data { return Data(HMAC.authenticationCode(for: message, using: SymmetricKey(data: key))) From 4382d167bcecd7d1a6cd778b93e2a8ad31a320ae Mon Sep 17 00:00:00 2001 From: mironal Date: Mon, 11 Apr 2022 09:28:03 +0900 Subject: [PATCH 6/6] linux build action --- .github/workflows/swift.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/swift.yml b/.github/workflows/swift.yml index 49d40132..ca8b6e7c 100644 --- a/.github/workflows/swift.yml +++ b/.github/workflows/swift.yml @@ -8,7 +8,11 @@ on: jobs: build: - runs-on: macos-latest + name: Lint & Build swift on ${{ matrix.os }} + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest, macos-latest] steps: - uses: actions/checkout@v2 - uses: actions/cache@v2