Skip to content

Commit

Permalink
Added comments for CryptorHeaderWithinStreamFinder and provides more …
Browse files Browse the repository at this point in the history
…readable error descriptions
  • Loading branch information
jguz-pubnub committed Sep 26, 2023
1 parent 988f8ae commit b57f156
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 23 deletions.
28 changes: 21 additions & 7 deletions Sources/PubNub/Helpers/Crypto/CryptorModule.swift
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,10 @@ public struct CryptorModule {
guard let cryptor = cryptor(matching: header) else {
return .failure(PubNubError(
.unknownCryptorError,
additional: ["Cannot find matching Cryptor for \(header.cryptorId())"]
additional: [
"Could not find matching Cryptor for \(header.cryptorId()) while decrypting Data. " +
"Ensure the corresponding instance is registered in \(String(describing: Self.self))"
]
))
}
return cryptor.decrypt(
Expand All @@ -78,7 +81,11 @@ public struct CryptorModule {
} catch let error as PubNubError {
return .failure(error)
} catch {
return .failure(PubNubError(.unknownCryptorError, additional: ["Cannot decrypt InputStream"]))
return .failure(PubNubError(
.decryptionError,
underlying: error,
additional: ["Cannot decrypt InputStream"])
)
}
}

Expand Down Expand Up @@ -116,7 +123,10 @@ public struct CryptorModule {
guard let cryptor = cryptor(matching: readHeaderResponse.header) else {
return .failure(PubNubError(
.unknownCryptorError,
additional: ["Cannot find matching Cryptor for \(readHeaderResponse.header.cryptorId())"]
additional: [
"Could not find matching Cryptor for \(readHeaderResponse.header.cryptorId()) while decrypting InputStream. " +
"Ensure the corresponding instance is registered in \(String(describing: Self.self))"
]
))
}
return cryptor.decrypt(
Expand All @@ -132,7 +142,11 @@ public struct CryptorModule {
} catch let error as PubNubError {
return .failure(error)
} catch {
return .failure(PubNubError(.unknownCryptorError, additional: ["Cannot decrypt InputStream"]))
return .failure(PubNubError(
.decryptionError,
underlying: error,
additional: ["Could not decrypt InputStream"])
)
}
}

Expand Down Expand Up @@ -166,7 +180,7 @@ extension CryptorModule: Hashable {

extension CryptorModule: CustomStringConvertible {
public var description: String {
"Default cryptor: \(defaultCryptor.id), other: \(cryptors.map { $0.id })"
"Default cryptor: \(defaultCryptor.id), others: \(cryptors.map { $0.id })"
}
}

Expand All @@ -175,7 +189,7 @@ internal extension CryptorModule {
guard let data = string.data(using: defaultStringEncoding) else {
return .failure(PubNubError(
.encryptionError,
additional: ["Cannot create Data from provided \(string)"]
additional: ["Cannot create Data from provided String"]
))
}
return encrypt(data: data).map {
Expand All @@ -190,7 +204,7 @@ internal extension CryptorModule {
} else {
return .failure(PubNubError(
.decryptionError,
additional: ["Cannot create String from provided Data \(data)"])
additional: ["Cannot create String from provided Data"])
)
}
}
Expand Down
28 changes: 14 additions & 14 deletions Sources/PubNub/Helpers/Crypto/Header/CryptorHeader.swift
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,8 @@ enum CryptorHeader: Equatable {
}

func asData() -> Data {
guard case .v1(let cryptorId, let data) = self else {
return Data()
}
guard case .v1(let cryptorId, let data) = self else { return Data() }

var finalData = sentinel.data(using: .ascii) ?? Data()
finalData += Data(bytes: [1], count: 1)
finalData += Data(bytes: cryptorId, count: cryptorId.count)
Expand Down Expand Up @@ -108,6 +107,7 @@ fileprivate class CryptorHeaderDataScanner {

struct CryptorHeaderParser {
private let scanner: CryptorHeaderDataScanner
private let supportedVersionsRange: ClosedRange<UInt8> = (1...1)

init(data: Data) {
self.scanner = CryptorHeaderDataScanner(data: data)
Expand All @@ -128,32 +128,32 @@ struct CryptorHeaderParser {
return .none
}
guard let headerVersion = scanner.nextByte() else {
throw PubNubError(.decryptionError, additional: ["Cannot find CryptorHeader's version byte"])
throw PubNubError(.decryptionError, additional: ["Could not find CryptorHeader version"])
}
guard (1...1).contains(headerVersion) else {
throw PubNubError(.unknownCryptorError, additional: ["Invalid CryptorHeader's version \(headerVersion)"])
guard supportedVersionsRange.contains(headerVersion) else {
throw PubNubError(.unknownCryptorError, additional: ["Unsupported or invalid CryptorHeader version \(headerVersion)"])
}
guard let cryptorId = scanner.nextBytes(4) else {
throw PubNubError(.decryptionError, additional: ["Cannot find Cryptor identifier"])
throw PubNubError(.decryptionError, additional: ["Could not find Cryptor identifier"])
}
guard let cryptorDataSize = scanner.nextByte() else {
throw PubNubError(.decryptionError, additional: ["Cannot read Cryptor data size"])
guard let cryptorDataSizeByte = scanner.nextByte() else {
throw PubNubError(.decryptionError, additional: ["Could not find Cryptor data size byte"])
}
guard let cryptorDefinedData = scanner.nextBytes(Int(try computeCryptorDataSize(with: cryptorDataSize))) else {
throw PubNubError(.decryptionError, additional: ["Cannot retrieve Cryptor defined data"])
guard let cryptorDefinedData = scanner.nextBytes(Int(try computeCryptorDataSize(with: Int(cryptorDataSizeByte)))) else {
throw PubNubError(.decryptionError, additional: ["Could not retrieve Cryptor defined data"])
}
return .v1(
cryptorId: cryptorId.map { $0 },
data: cryptorDefinedData
)
}

private func computeCryptorDataSize(with sizeIndicator: UInt8) throws -> UInt16 {
if sizeIndicator < UInt8.max {
private func computeCryptorDataSize(with sizeIndicator: Int) throws -> UInt16 {
guard sizeIndicator > 255 else {
return UInt16(sizeIndicator)
}
guard let nextBytes = scanner.nextBytes(2) else {
throw PubNubError(.unknownCryptorError, additional: ["Cannot read next Cryptor data size bytes"])
throw PubNubError(.unknownCryptorError, additional: ["Could not find next Cryptor data size bytes"])
}
return nextBytes.withUnsafeBytes {
$0.load(as: UInt16.self)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ import Foundation
struct CryptorHeaderWithinStreamFinder {
let stream: InputStream

// Attempts to find CryptorHeader at the beginning of the given InputStream.
// Returns CryptorHeader (if any) and InputStream starting with encoded content
func findHeader() throws -> (header: CryptorHeader, continuationStream: InputStream) {
let possibleHeaderBytes = read(maxLength: 100)
let parsingRes = try CryptorHeaderParser(data: possibleHeaderBytes).parseAndReturnProcessedBytes()
Expand All @@ -39,13 +41,20 @@ struct CryptorHeaderWithinStreamFinder {
switch parsingRes.header {
case .none:
continuationStream = MultipartInputStream(
inputStreams: [InputStream(data: possibleHeaderBytes), stream]
inputStreams: [
InputStream(data: possibleHeaderBytes),
stream
]
)
default:
continuationStream = MultipartInputStream(
inputStreams: [InputStream(data: possibleHeaderBytes.suffix(from: noOfBytesProcessedByParser)), stream]
inputStreams: [
InputStream(data: possibleHeaderBytes.suffix(from: noOfBytesProcessedByParser)),
stream
]
)
}

return (
header: parsingRes.header,
continuationStream: continuationStream
Expand Down

0 comments on commit b57f156

Please sign in to comment.