Make it run on Catalina

closes #158, closes #77
This commit is contained in:
Grishka
2024-05-23 00:07:12 +03:00
parent 10d63f13bd
commit 5e69970af8
11 changed files with 102 additions and 59 deletions

View File

@@ -103,7 +103,7 @@ class InboundNearbyConnection: NearbyConnection{
guard frame.payloadChunk.offset==currentOffset else { throw NearbyError.protocolError("Invalid offset into file \(frame.payloadChunk.offset), expected \(currentOffset)") }
guard currentOffset+Int64(frame.payloadChunk.body.count)<=fileInfo.meta.size else { throw NearbyError.protocolError("Transferred file size exceeds previously specified value") }
if frame.payloadChunk.body.count>0{
try fileInfo.fileHandle?.write(contentsOf: frame.payloadChunk.body)
fileInfo.fileHandle?.write(frame.payloadChunk.body)
transferredFiles[id]!.bytesTransferred+=Int64(frame.payloadChunk.body.count)
fileInfo.progress?.completedUnitCount=transferredFiles[id]!.bytesTransferred
}else if (frame.payloadChunk.flags & 1)==1{

View File

@@ -319,6 +319,31 @@ class NearbyConnection{
return String(format: "%04d", abs(hash))
}
internal static func hkdfExtract(salt:Data, ikm:Data) -> Data{
return HMAC<SHA256>.authenticationCode(for: ikm, using: SymmetricKey(data: salt)).withUnsafeBytes({return Data(bytes: $0.baseAddress!, count: $0.count)})
}
internal static func hkdfExpand(prk:Data, info:Data, length:Int) -> Data{
var okm=Data()
var t=Data()
var i=0
while okm.count<length{
i=i+1
let toDigest=t+info+Data([UInt8(truncatingIfNeeded: i)])
t=HMAC<SHA256>.authenticationCode(for: toDigest, using: SymmetricKey(data: prk)).withUnsafeBytes({return Data(bytes: $0.baseAddress!, count: $0.count)})
okm=okm+t
}
return okm.subdata(in: 0..<length)
}
internal static func hkdf(inputKeyMaterial:SymmetricKey, salt:Data, info:Data, outputByteCount:Int) -> SymmetricKey{
if #available(macOS 11.0, *){
return HKDF<SHA256>.deriveKey(inputKeyMaterial: inputKeyMaterial, salt: salt, info: info, outputByteCount: outputByteCount)
}else{
return SymmetricKey(data: hkdfExpand(prk: hkdfExtract(salt: salt, ikm: inputKeyMaterial.withUnsafeBytes({return Data(bytes: $0.baseAddress!, count: $0.count)})), info: info, length: outputByteCount))
}
}
internal func finalizeKeyExchange(peerKey:Securemessage_GenericPublicKey) throws{
guard peerKey.hasEcP256PublicKey else { throw NearbyError.requiredFieldMissing("peerKey.ecP256PublicKey") }
@@ -341,8 +366,8 @@ class NearbyConnection{
var ukeyInfo=Data()
ukeyInfo.append(ukeyClientInitMsgData!)
ukeyInfo.append(ukeyServerInitMsgData!)
let authString=HKDF<SHA256>.deriveKey(inputKeyMaterial: SymmetricKey(data: derivedSecretKey), salt: "UKEY2 v1 auth".data(using: .utf8)!, info: ukeyInfo, outputByteCount: 32)
let nextSecret=HKDF<SHA256>.deriveKey(inputKeyMaterial: SymmetricKey(data: derivedSecretKey), salt: "UKEY2 v1 next".data(using: .utf8)!, info: ukeyInfo, outputByteCount: 32)
let authString=NearbyConnection.hkdf(inputKeyMaterial: SymmetricKey(data: derivedSecretKey), salt: "UKEY2 v1 auth".data(using: .utf8)!, info: ukeyInfo, outputByteCount: 32)
let nextSecret=NearbyConnection.hkdf(inputKeyMaterial: SymmetricKey(data: derivedSecretKey), salt: "UKEY2 v1 next".data(using: .utf8)!, info: ukeyInfo, outputByteCount: 32)
pinCode=NearbyConnection.pinCodeFromAuthKey(authString)
@@ -350,17 +375,17 @@ class NearbyConnection{
0xEE, 0x8D, 0x39, 0x09, 0xB9, 0x5F, 0x13, 0xFA, 0x7D, 0xEB, 0x1D,
0x4A, 0xB3, 0x83, 0x76, 0xB8, 0x25, 0x6D, 0xA8, 0x55, 0x10])
let d2dClientKey=HKDF<SHA256>.deriveKey(inputKeyMaterial: nextSecret, salt: salt, info: "client".data(using: .utf8)!, outputByteCount: 32)
let d2dServerKey=HKDF<SHA256>.deriveKey(inputKeyMaterial: nextSecret, salt: salt, info: "server".data(using: .utf8)!, outputByteCount: 32)
let d2dClientKey=NearbyConnection.hkdf(inputKeyMaterial: nextSecret, salt: salt, info: "client".data(using: .utf8)!, outputByteCount: 32)
let d2dServerKey=NearbyConnection.hkdf(inputKeyMaterial: nextSecret, salt: salt, info: "server".data(using: .utf8)!, outputByteCount: 32)
sha=SHA256()
sha.update(data: "SecureMessage".data(using: .utf8)!)
let smsgSalt=Data(sha.finalize())
let clientKey=HKDF<SHA256>.deriveKey(inputKeyMaterial: d2dClientKey, salt: smsgSalt, info: "ENC:2".data(using: .utf8)!, outputByteCount: 32).withUnsafeBytes({return [UInt8]($0)})
let clientHmacKey=HKDF<SHA256>.deriveKey(inputKeyMaterial: d2dClientKey, salt: smsgSalt, info: "SIG:1".data(using: .utf8)!, outputByteCount: 32)
let serverKey=HKDF<SHA256>.deriveKey(inputKeyMaterial: d2dServerKey, salt: smsgSalt, info: "ENC:2".data(using: .utf8)!, outputByteCount: 32).withUnsafeBytes({return [UInt8]($0)})
let serverHmacKey=HKDF<SHA256>.deriveKey(inputKeyMaterial: d2dServerKey, salt: smsgSalt, info: "SIG:1".data(using: .utf8)!, outputByteCount: 32)
let clientKey=NearbyConnection.hkdf(inputKeyMaterial: d2dClientKey, salt: smsgSalt, info: "ENC:2".data(using: .utf8)!, outputByteCount: 32).withUnsafeBytes({return [UInt8]($0)})
let clientHmacKey=NearbyConnection.hkdf(inputKeyMaterial: d2dClientKey, salt: smsgSalt, info: "SIG:1".data(using: .utf8)!, outputByteCount: 32)
let serverKey=NearbyConnection.hkdf(inputKeyMaterial: d2dServerKey, salt: smsgSalt, info: "ENC:2".data(using: .utf8)!, outputByteCount: 32).withUnsafeBytes({return [UInt8]($0)})
let serverHmacKey=NearbyConnection.hkdf(inputKeyMaterial: d2dServerKey, salt: smsgSalt, info: "SIG:1".data(using: .utf8)!, outputByteCount: 32)
if isServer(){
decryptKey=clientKey

View File

@@ -53,7 +53,7 @@ public enum NearbyError:Error{
case protocolError(_ message:String)
case requiredFieldMissing(_ message:String)
case ukey2
case inputOutput(cause:Errno)
case inputOutput
case canceled(reason:CancellationReason)
public enum CancellationReason{

View File

@@ -277,9 +277,15 @@ class OutboundNearbyConnection:NearbyConnection{
let typeID=try? url.resourceValues(forKeys: [.typeIdentifierKey]).typeIdentifier
meta.mimeType="application/octet-stream"
if let typeID=typeID{
let type=UTType(typeID)
if let type=type, let mimeType=type.preferredMIMEType{
meta.mimeType=mimeType
if #available(macOS 11.0, *){
let type=UTType(typeID)
if let type=type, let mimeType=type.preferredMIMEType{
meta.mimeType=mimeType
}
}else{
if let mimeType=UTTypeCopyPreferredTagWithClass(typeID as CFString, kUTTagClassMIMEType){
meta.mimeType=(mimeType.takeRetainedValue() as NSString) as String
}
}
}
if meta.mimeType.starts(with: "image/"){
@@ -358,8 +364,14 @@ class OutboundNearbyConnection:NearbyConnection{
currentTransfer=queue.removeFirst()
}
guard let fileBuffer=try currentTransfer!.handle!.read(upToCount: 512*1024) else{
throw NearbyError.inputOutput(cause: Errno.ioError)
let fileBuffer:Data
if #available(macOS 10.15.4, *) {
guard let _fileBuffer=try currentTransfer!.handle!.read(upToCount: 512*1024) else{
throw NearbyError.inputOutput
}
fileBuffer=_fileBuffer
} else {
fileBuffer=currentTransfer!.handle!.readData(ofLength: 512*1024)
}
var transfer=Location_Nearby_Connections_PayloadTransferFrame()