From 921b9237f7fea11380a52801b31e21bbb06ce8eb Mon Sep 17 00:00:00 2001 From: Christoph Hagen Date: Thu, 28 Apr 2022 23:19:44 +0200 Subject: [PATCH] Proper serialization and cleanup --- Sesame.xcodeproj/project.pbxproj | 8 +- .../UserInterfaceState.xcuserstate | Bin 53576 -> 71271 bytes Sesame/API/Message+Extensions.swift | 38 ------ Sesame/API/Message.swift | 117 +++++++++++------- Sesame/API/UInt32+Extensions.swift | 18 +++ Sesame/Data+Extensions.swift | 17 +++ 6 files changed, 110 insertions(+), 88 deletions(-) delete mode 100644 Sesame/API/Message+Extensions.swift create mode 100644 Sesame/API/UInt32+Extensions.swift diff --git a/Sesame.xcodeproj/project.pbxproj b/Sesame.xcodeproj/project.pbxproj index cfa6890..3081a47 100644 --- a/Sesame.xcodeproj/project.pbxproj +++ b/Sesame.xcodeproj/project.pbxproj @@ -20,8 +20,8 @@ E24EE77427FF95920011CFD2 /* DeviceResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = E24EE77327FF95920011CFD2 /* DeviceResponse.swift */; }; E24EE77727FF95C00011CFD2 /* NIOCore in Frameworks */ = {isa = PBXBuildFile; productRef = E24EE77627FF95C00011CFD2 /* NIOCore */; }; E24EE77927FF95E00011CFD2 /* Message.swift in Sources */ = {isa = PBXBuildFile; fileRef = E24EE77827FF95E00011CFD2 /* Message.swift */; }; - E24EE77B280058240011CFD2 /* Message+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = E24EE77A280058240011CFD2 /* Message+Extensions.swift */; }; E2C5C1DB2806FE8900769EF6 /* RouteAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2C5C1DA2806FE8900769EF6 /* RouteAPI.swift */; }; + E2C5C1DD281B3AC400769EF6 /* UInt32+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2C5C1DC281B3AC400769EF6 /* UInt32+Extensions.swift */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -38,8 +38,8 @@ E24EE77127FDCCC00011CFD2 /* Data+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Data+Extensions.swift"; sourceTree = ""; }; E24EE77327FF95920011CFD2 /* DeviceResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeviceResponse.swift; sourceTree = ""; }; E24EE77827FF95E00011CFD2 /* Message.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Message.swift; sourceTree = ""; }; - E24EE77A280058240011CFD2 /* Message+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Message+Extensions.swift"; sourceTree = ""; }; E2C5C1DA2806FE8900769EF6 /* RouteAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RouteAPI.swift; sourceTree = ""; }; + E2C5C1DC281B3AC400769EF6 /* UInt32+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UInt32+Extensions.swift"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -102,7 +102,7 @@ E24EE77827FF95E00011CFD2 /* Message.swift */, 884A45CE27A5402D00D6E650 /* MessageResult.swift */, E2C5C1DA2806FE8900769EF6 /* RouteAPI.swift */, - E24EE77A280058240011CFD2 /* Message+Extensions.swift */, + E2C5C1DC281B3AC400769EF6 /* UInt32+Extensions.swift */, ); path = API; sourceTree = ""; @@ -186,8 +186,8 @@ 884A45CF27A5402D00D6E650 /* MessageResult.swift in Sources */, 884A45B9279F48C100D6E650 /* ContentView.swift in Sources */, E2C5C1DB2806FE8900769EF6 /* RouteAPI.swift in Sources */, + E2C5C1DD281B3AC400769EF6 /* UInt32+Extensions.swift in Sources */, 884A45CD27A465F500D6E650 /* Client.swift in Sources */, - E24EE77B280058240011CFD2 /* Message+Extensions.swift in Sources */, E24EE77227FDCCC00011CFD2 /* Data+Extensions.swift in Sources */, E24EE77427FF95920011CFD2 /* DeviceResponse.swift in Sources */, 884A45CB27A464C000D6E650 /* SymmetricKey+Extensions.swift in Sources */, diff --git a/Sesame.xcodeproj/project.xcworkspace/xcuserdata/ch.xcuserdatad/UserInterfaceState.xcuserstate b/Sesame.xcodeproj/project.xcworkspace/xcuserdata/ch.xcuserdatad/UserInterfaceState.xcuserstate index e737ffad157d3e1eba90918a218e7b65f78c44d6..dff6be4f0f20814a9ff667c23e3ddcdcebfcf3df 100644 GIT binary patch literal 71271 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 AL;wH) delta 25345 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 diff --git a/Sesame/API/Message+Extensions.swift b/Sesame/API/Message+Extensions.swift deleted file mode 100644 index 38fb2b9..0000000 --- a/Sesame/API/Message+Extensions.swift +++ /dev/null @@ -1,38 +0,0 @@ -import Foundation - -#if canImport(CryptoKit) -import CryptoKit -#else -import Crypto -#endif - -extension Message { - - static var length: Int { - SHA256.byteCount + Content.length - } - - init(decodeFrom data: T) where T.Element == UInt8 { - let count = SHA256.byteCount - self.mac = Data(data.prefix(count)) - self.content = .init(decodeFrom: Array(data.dropFirst(count))) - } - - func isValid(using key: SymmetricKey) -> Bool { - HMAC.isValidAuthenticationCode(mac, authenticating: content.encoded, using: key) - } -} - -extension Message.Content { - - func authenticate(using key: SymmetricKey) -> Message { - let mac = HMAC.authenticationCode(for: encoded, using: key) - return .init(mac: Data(mac.map { $0 }), content: self) - } - - func authenticateAndSerialize(using key: SymmetricKey) -> Data { - let encoded = self.encoded - let mac = HMAC.authenticationCode(for: encoded, using: key) - return Data(mac.map { $0 }) + encoded - } -} diff --git a/Sesame/API/Message.swift b/Sesame/API/Message.swift index 60ede14..4bed14a 100644 --- a/Sesame/API/Message.swift +++ b/Sesame/API/Message.swift @@ -1,11 +1,36 @@ import Foundation import NIOCore +#if canImport(CryptoKit) +import CryptoKit +#else +import Crypto +#endif + /** An authenticated message to or from the device. */ struct Message: Equatable, Hashable { + /// The message authentication code for the message (32 bytes) + let mac: Data + + /// The message content + let content: Content + + /** + Create an authenticated message + - Parameter mac: The message authentication code + - Parameter content: The message content + */ + init(mac: Data, content: Content) { + self.mac = mac + self.content = content + } +} + +extension Message { + /** The message content without authentication. */ @@ -30,13 +55,13 @@ struct Message: Equatable, Hashable { /** Decode message content from data. - The data consists of two `UInt32` encoded in big endian format (MSB at index 0) + The data consists of two `UInt32` encoded in little endian format - Warning: The sequence must contain at least 8 bytes, or the function will crash. - Parameter data: The sequence containing the bytes. */ init(decodeFrom data: T) where T.Element == UInt8 { - self.time = UInt32(data: data.prefix(MemoryLayout.size)) - self.id = UInt32(data: data.dropFirst(MemoryLayout.size)) + self.time = UInt32(data: Data(data.prefix(MemoryLayout.size))) + self.id = UInt32(data: Data(data.dropFirst(MemoryLayout.size))) } /// The byte length of an encoded message content @@ -48,27 +73,15 @@ struct Message: Equatable, Hashable { var encoded: Data { time.encoded + id.encoded } - - /// The message content encoded to bytes - var bytes: [UInt8] { - time.bytes + id.bytes - } } - /// The message authentication code for the message (32 bytes) - let mac: Data +} - /// The message content - let content: Content +extension Message { - /** - Create an authenticated message - - Parameter mac: The message authentication code - - Parameter content: The message content - */ - init(mac: Data, content: Content) { - self.mac = mac - self.content = content + /// The length of a message in bytes + static var length: Int { + SHA256.byteCount + Content.length } /** @@ -88,35 +101,47 @@ struct Message: Equatable, Hashable { mac + content.encoded } - /// The message encoded to bytes - var bytes: [UInt8] { - Array(mac) + content.bytes + /** + Create a message from received bytes. + - Parameter data: The sequence of bytes + - Note: The sequence must contain at least `Message.length` bytes, or the function will crash. + */ + init(decodeFrom data: T) where T.Element == UInt8 { + let count = SHA256.byteCount + self.mac = Data(data.prefix(count)) + self.content = .init(decodeFrom: Array(data.dropFirst(count))) + } + + /** + Check if the message contains a valid authentication code + - Parameter key: The key used to sign the message. + - Returns: `true`, if the message is valid. + */ + func isValid(using key: SymmetricKey) -> Bool { + HMAC.isValidAuthenticationCode(mac, authenticating: content.encoded, using: key) } } - extension UInt32 { +extension Message.Content { - /** - Create a value from a big-endian data representation (MSB first) - - Note: The data must contain exactly four bytes. - */ - init(data: T) where T.Element == UInt8 { - self = data - .reversed() - .enumerated() - .map { UInt32($0.element) << ($0.offset * 8) } - .reduce(0, +) - } + /** + Calculate an authentication code for the message content. + - Parameter key: The key to use to sign the content. + - Returns: The new message signed with the key. + */ + func authenticate(using key: SymmetricKey) -> Message { + let mac = HMAC.authenticationCode(for: encoded, using: key) + return .init(mac: Data(mac.map { $0 }), content: self) + } - /// The value encoded to a big-endian representation - var encoded: Data { - .init(bytes) - } - - /// The value encoded to a big-endian byte array - var bytes: [UInt8] { - (0..<4).reversed().map { - UInt8((self >> ($0*8)) & 0xFF) - } - } + /** + Calculate an authentication code for the message content and convert everything to data. + - Parameter key: The key to use to sign the content. + - Returns: The new message signed with the key, serialized to bytes. + */ + func authenticateAndSerialize(using key: SymmetricKey) -> Data { + let encoded = self.encoded + let mac = HMAC.authenticationCode(for: encoded, using: key) + return Data(mac.map { $0 }) + encoded + } } diff --git a/Sesame/API/UInt32+Extensions.swift b/Sesame/API/UInt32+Extensions.swift new file mode 100644 index 0000000..90708ef --- /dev/null +++ b/Sesame/API/UInt32+Extensions.swift @@ -0,0 +1,18 @@ +import Foundation + +extension UInt32 { + + /** + Create a value from a little-endian data representation (MSB first) + - Note: The data must contain exactly four bytes. + */ + init(data: Data) { + let value = data.convert(into: UInt32.zero) + self = CFSwapInt32LittleToHost(value) + } + + /// The value encoded to a little-endian representation + var encoded: Data { + Data(from: CFSwapInt32HostToLittle(self)) + } +} diff --git a/Sesame/Data+Extensions.swift b/Sesame/Data+Extensions.swift index f36b39f..159efeb 100644 --- a/Sesame/Data+Extensions.swift +++ b/Sesame/Data+Extensions.swift @@ -40,3 +40,20 @@ extension Data { } } } + +extension Data { + + + func convert(into value: T) -> T { + withUnsafeBytes { + $0.baseAddress!.load(as: T.self) + } + } + + init(from value: T) { + var target = value + self = Swift.withUnsafeBytes(of: &target) { + Data($0) + } + } +}