mirror of https://github.com/oxen-io/session-ios
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
62 lines
2.1 KiB
Swift
62 lines
2.1 KiB
Swift
// Copyright © 2022 Rangeproof Pty Ltd. All rights reserved.
|
|
|
|
import Foundation
|
|
import SessionUtilitiesKit
|
|
|
|
// MARK: - Log.Category
|
|
|
|
private extension Log.Category {
|
|
static let cat: Log.Category = .create("Data", defaultLevel: .warn)
|
|
}
|
|
|
|
// MARK: - Decoding
|
|
|
|
public extension Data {
|
|
func removePadding() -> Data {
|
|
let bytes: [UInt8] = self.bytes
|
|
var paddingStart: Int = self.count
|
|
|
|
for i in 0..<(self.count - 1) {
|
|
let targetIndex: Int = ((self.count - 1) - i)
|
|
|
|
if bytes[targetIndex] == 0x80 {
|
|
paddingStart = targetIndex
|
|
break
|
|
}
|
|
else if bytes[targetIndex] != 0x00 {
|
|
Log.error(.cat, "Failed to remove padding, returning unstripped padding");
|
|
return self
|
|
}
|
|
}
|
|
|
|
return self.prefix(upTo: paddingStart)
|
|
}
|
|
|
|
func paddedMessageBody() -> Data {
|
|
// From
|
|
// https://github.com/signalapp/TextSecure/blob/master/libtextsecure/src/main/java/org/whispersystems/textsecure/internal/push/PushTransportDetails.java#L55
|
|
// NOTE: This is dumb. We have our own padding scheme, but so does the cipher.
|
|
// The +1 -1 here is to make sure the Cipher has room to add one padding byte,
|
|
// otherwise it'll add a full 16 extra bytes.
|
|
let paddedMessageLength: Int = (self.paddedMessageLength(self.count + 1) - 1)
|
|
var paddedMessage: Data = Data(count: paddedMessageLength)
|
|
|
|
let paddingByte: UInt8 = 0x80
|
|
paddedMessage[0..<self.count] = Data(self.bytes)
|
|
paddedMessage[self.count..<(self.count + 1)] = Data([paddingByte])
|
|
|
|
return paddedMessage
|
|
}
|
|
|
|
private func paddedMessageLength(_ unpaddedLength: Int) -> Int {
|
|
let messageLengthWithTerminator: Int = (unpaddedLength + 1)
|
|
var messagePartCount: Int = (messageLengthWithTerminator / 160)
|
|
|
|
if CGFloat(messageLengthWithTerminator).truncatingRemainder(dividingBy: 160) != 0 {
|
|
messagePartCount += 1
|
|
}
|
|
|
|
return (messagePartCount * 160)
|
|
}
|
|
}
|