Skip to content

Commit

Permalink
CryptorModule
Browse files Browse the repository at this point in the history
* Reusing existing CryptoStream + CryptoInputStream by removing Crypto dependency from them
* Moved old encryption/decryption to LegacyCryptor
* Introduced new AESCBCCryptor
* Introduced new CryptorModule instead of Crypto
* Fixing tests
  • Loading branch information
jguz-pubnub committed Sep 21, 2023
1 parent cb04c77 commit 78da753
Show file tree
Hide file tree
Showing 33 changed files with 1,679 additions and 735 deletions.
2 changes: 1 addition & 1 deletion Examples/Sources/ConfigDetailTableViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ class ConfigDetailTableViewController: UITableViewController {
case .subscribeKey:
return config.subscribeKey
case .cipherKey:
return config.cipherKey?.key.description ?? "Key Not Found"
return config.cryptorModule?.description ?? "CryptorModule Not Found"
case .authKey:
return config.authKey
case .uuid:
Expand Down
2 changes: 1 addition & 1 deletion Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,4 @@ SPEC CHECKSUMS:

PODFILE CHECKSUM: 61a40240486621bb01f596fdd5bc632504940fab

COCOAPODS: 1.11.3
COCOAPODS: 1.12.1
202 changes: 190 additions & 12 deletions PubNub.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions Sources/PubNub/APIs/File+PubNub.swift
Original file line number Diff line number Diff line change
Expand Up @@ -160,9 +160,9 @@ public extension PubNub {
switch result {
case let .success(response):
do {
let autoCrypto = requestConfig.customConfiguration?.cipherKey ?? configuration.cipherKey
let cryptorModule = requestConfig.customConfiguration?.cryptorModule ?? configuration.cryptorModule
completion?(.success((
try URLRequest(from: response.payload, uploading: content, crypto: autoCrypto),
try URLRequest(from: response.payload, uploading: content, cryptorModule: cryptorModule),
response.payload.fileId,
response.payload.filename
)))
Expand Down Expand Up @@ -450,7 +450,7 @@ public extension PubNub {
/// - downloadTo: The async `Result` of the method call
/// - Returns: The new file download task. The `urlSessionTask` property can be used to access the underlying `URLSessionDownloadTask`
func createFileURLSessionDownloadTask(
_ taskType: FileDownloadTaskType, session: URLSessionReplaceable, downloadTo url: URL, decrypt: Crypto? = nil
_ taskType: FileDownloadTaskType, session: URLSessionReplaceable, downloadTo url: URL, decrypt: CryptorModule? = nil
) -> HTTPFileDownloadTask {
let downloadTask: URLSessionDownloadTask
switch taskType {
Expand All @@ -464,7 +464,7 @@ public extension PubNub {
task: downloadTask,
session: session.configuration.identifier,
downloadTo: url,
crypto: decrypt ?? configuration.cipherKey
cryptorModule: decrypt ?? configuration.cryptorModule
)

// Create task map inside Delegate
Expand Down
6 changes: 6 additions & 0 deletions Sources/PubNub/Errors/ErrorDescription.swift
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,12 @@ extension PubNubError.Reason: CustomStringConvertible, LocalizedError {
return "The Content-Length was incorrect for the content being uploaded"
case .serviceNotEnabled:
return "The PubNub Service that you're attempting to use has not be enabled for your keyset."
case .encryptionError:
return "Failure performing an encryption operation"
case .decryptionError:
return "Failure performing a decryption operation"
case .unknownCryptorError:
return "Unknown Cryptor error"
}
}

Expand Down
5 changes: 5 additions & 0 deletions Sources/PubNub/Errors/PubNubError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,9 @@ public struct PubNubError: Error {

// Crypto
case missingCryptoKey
case encryptionError
case decryptionError
case unknownCryptorError

// Request Processing
case requestMutatorFailure
Expand Down Expand Up @@ -232,6 +235,8 @@ public struct PubNubError: Error {
return .streamFailure
case .fileTooLarge, .fileMissingAtPath, .fileAccessDenied, .fileContentLength:
return .fileManagement
case .encryptionError, .decryptionError, .unknownCryptorError:
return .crypto
}
}
}
Expand Down
42 changes: 22 additions & 20 deletions Sources/PubNub/Extensions/URLRequest+PubNub.swift
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public extension URLRequest {
internal init(
from response: GenerateUploadURLResponse,
uploading content: PubNub.FileUploadContent,
crypto: Crypto? = nil
cryptorModule: CryptorModule? = nil
) throws {
self.init(url: response.uploadRequestURL)
method = response.uploadMethod
Expand All @@ -65,30 +65,32 @@ public extension URLRequest {
postfixData.append("\r\n--\(response.fileId)--")

// Get Content InputStream
guard var contentStream = content.inputStream else {
guard let contentStream = content.inputStream else {
throw PubNubError(.streamCouldNotBeInitialized, additional: [content.debugDescription])
}

// If we were given a Crypto payload we should convert the stream to a secure stream
if let crypto = crypto {
let cryptoStream = CryptoInputStream(
.encrypt, input: contentStream, contentLength: content.contentLength, with: crypto
)
setValue(
"\(prefixData.count + cryptoStream.estimatedCryptoCount + postfixData.count)",
forHTTPHeaderField: "Content-Length"
)
contentStream = cryptoStream

let finalStream: InputStream
let contentLength: Int

// If we were given a Crypto module we should convert the stream to a secure stream
if let cryptorModule = cryptorModule {
switch cryptorModule.encrypt(stream: contentStream, contentLength: content.contentLength) {
case .success(let encryptingResult):
finalStream = encryptingResult.stream
contentLength = prefixData.count + encryptingResult.contentLength + postfixData.count
case .failure(let encryptionError):
throw encryptionError
}
} else {
setValue("\(prefixData.count + content.contentLength + postfixData.count)", forHTTPHeaderField: "Content-Length")
finalStream = contentStream
contentLength = prefixData.count + content.contentLength + postfixData.count
}

let inputStream = MultipartInputStream(
inputStreams: [InputStream(data: prefixData), contentStream, InputStream(data: postfixData)]
)

httpBodyStream = inputStream

setValue("\(contentLength)", forHTTPHeaderField: "Content-Length")
setValue("multipart/form-data; boundary=\(response.fileId)", forHTTPHeaderField: "Content-Type")

httpBodyStream = MultipartInputStream(
inputStreams: [InputStream(data: prefixData), finalStream, InputStream(data: postfixData)]
)
}
}
Loading

0 comments on commit 78da753

Please sign in to comment.