From cb145c06bcba6a127eb4cb8eaa67e342029b692a Mon Sep 17 00:00:00 2001 From: Gereon Steffens Date: Fri, 24 May 2019 17:03:06 +0200 Subject: [PATCH] Swift 5 compatibility --- OneTimePassword.podspec | 2 +- OneTimePassword.xcodeproj/project.pbxproj | 4 ++-- Sources/Crypto.swift | 8 ++++++++ Sources/Generator.swift | 11 +++++++++++ 4 files changed, 22 insertions(+), 3 deletions(-) diff --git a/OneTimePassword.podspec b/OneTimePassword.podspec index 6907565d..91b3c1a5 100644 --- a/OneTimePassword.podspec +++ b/OneTimePassword.podspec @@ -5,7 +5,7 @@ Pod::Spec.new do |s| s.homepage = "https://github.com/mattrubin/OneTimePassword" s.license = "MIT" s.author = "Matt Rubin" - s.swift_version = "4.2" + s.swift_versions = ["4.2", "5.0"] s.ios.deployment_target = "8.0" s.watchos.deployment_target = "2.0" s.source = { :git => "https://github.com/mattrubin/OneTimePassword.git", :tag => s.version } diff --git a/OneTimePassword.xcodeproj/project.pbxproj b/OneTimePassword.xcodeproj/project.pbxproj index 0d4e142f..7ce32c72 100644 --- a/OneTimePassword.xcodeproj/project.pbxproj +++ b/OneTimePassword.xcodeproj/project.pbxproj @@ -684,7 +684,7 @@ buildSettings = { IPHONEOS_DEPLOYMENT_TARGET = 8.0; SWIFT_TREAT_WARNINGS_AS_ERRORS = NO; - SWIFT_VERSION = 4.2; + SWIFT_VERSION = 5.0; WATCHOS_DEPLOYMENT_TARGET = 2.0; }; name = Debug; @@ -695,7 +695,7 @@ buildSettings = { IPHONEOS_DEPLOYMENT_TARGET = 8.0; SWIFT_TREAT_WARNINGS_AS_ERRORS = NO; - SWIFT_VERSION = 4.2; + SWIFT_VERSION = 5.0; WATCHOS_DEPLOYMENT_TARGET = 2.0; }; name = Release; diff --git a/Sources/Crypto.swift b/Sources/Crypto.swift index e3ea067d..afdfe7e5 100644 --- a/Sources/Crypto.swift +++ b/Sources/Crypto.swift @@ -34,11 +34,19 @@ func HMAC(algorithm: Generator.Algorithm, key: Data, data: Data) -> Data { macOut.deallocate() } + #if swift(>=5.0) + key.withUnsafeBytes { keyBytes in + data.withUnsafeBytes { dataBytes in + CCHmac(hashFunction, keyBytes.baseAddress, key.count, dataBytes.baseAddress, data.count, macOut) + } + } + #else key.withUnsafeBytes { keyBytes in data.withUnsafeBytes { dataBytes in CCHmac(hashFunction, keyBytes, key.count, dataBytes, data.count, macOut) } } + #endif return Data(bytes: macOut, count: hashLength) } diff --git a/Sources/Generator.swift b/Sources/Generator.swift index 716ad486..b0f420d7 100644 --- a/Sources/Generator.swift +++ b/Sources/Generator.swift @@ -86,6 +86,16 @@ public struct Generator: Equatable { let counterData = Data(bytes: &bigCounter, count: MemoryLayout.size) let hash = HMAC(algorithm: algorithm, key: secret, data: counterData) + #if swift(>=5.0) + var truncatedHash = hash.withUnsafeBytes { ptr -> UInt32 in + // Use the last 4 bits of the hash as an offset (0 <= offset <= 15) + let offset = ptr[hash.count - 1] & 0x0f + + // Take 4 bytes from the hash, starting at the given byte offset + let truncatedHashPtr = ptr.baseAddress! + Int(offset) + return truncatedHashPtr.bindMemory(to: UInt32.self, capacity: 1).pointee + } + #else var truncatedHash = hash.withUnsafeBytes { (ptr: UnsafePointer) -> UInt32 in // Use the last 4 bits of the hash as an offset (0 <= offset <= 15) let offset = ptr[hash.count - 1] & 0x0f @@ -96,6 +106,7 @@ public struct Generator: Equatable { $0.pointee } } + #endif // Ensure the four bytes taken from the hash match the current endian format truncatedHash = UInt32(bigEndian: truncatedHash)