Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CryptorModule #144

Merged
merged 16 commits into from
Oct 16, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions Sources/PubNub/Errors/ErrorDescription.swift
Original file line number Diff line number Diff line change
Expand Up @@ -294,11 +294,11 @@ 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:
case .encryptionFailure:
return "Failure to perform encryption"
case .decryptionError:
case .decryptionFailure:
return "Failure to perform decryption"
case .unknownCryptorError:
case .unknownCryptorFailure:
return "Unknown Cryptor error"
}
}
Expand Down
8 changes: 4 additions & 4 deletions Sources/PubNub/Errors/PubNubError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,9 @@ public struct PubNubError: Error {

// Crypto
case missingCryptoKey
case encryptionError
case decryptionError
case unknownCryptorError
case encryptionFailure
case decryptionFailure
case unknownCryptorFailure

// Request Processing
case requestMutatorFailure
Expand Down Expand Up @@ -235,7 +235,7 @@ public struct PubNubError: Error {
return .streamFailure
case .fileTooLarge, .fileMissingAtPath, .fileAccessDenied, .fileContentLength:
return .fileManagement
case .encryptionError, .decryptionError, .unknownCryptorError:
case .encryptionFailure, .decryptionFailure, .unknownCryptorFailure:
return .crypto
}
}
Expand Down
4 changes: 2 additions & 2 deletions Sources/PubNub/Extensions/URLRequest+PubNub.swift
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,8 @@ public extension URLRequest {
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
finalStream = encryptingResult
contentLength = prefixData.count + encryptingResult.length + postfixData.count
case .failure(let encryptionError):
throw encryptionError
}
Expand Down
48 changes: 48 additions & 0 deletions Sources/PubNub/Helpers/Crypto/CryptoError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,54 @@
import CommonCrypto
import Foundation

/// Object capable of encryption/decryption
///
/// - Warning: This struct is deprecated. Use ``CryptorModule`` instead.
public struct Crypto: Hashable {
/// The key used when encrypting/decrypting
public let key: Data
/// The String Encoding strategy to be used by default
public let defaultStringEncoding: String.Encoding
/// Whether random initialization vector should be used
public let randomizeIV: Bool

// Keeps originally provided input by the user
internal let keyString: String

public init?(key: String, withRandomIV: Bool = true, encoding: String.Encoding = .utf8) {
guard let data = key.data(using: encoding), let keyData = SHA256.hash(data: data) else {
PubNub.log.error("Crypto failed to `init` while converting `String` key to `Data`"); return nil
}

let keySize = keyData.count
let keySizeRange = (kCCKeySizeAES128 ... kCCKeySizeAES256)

if keySizeRange.contains(keyData.count) {
PubNub.log.error("Key size not valid for algorithm: \(keySize) not in \(keySizeRange)")
}

self.key = keyData
self.keyString = key
self.defaultStringEncoding = encoding
self.randomizeIV = withRandomIV
}

enum SHA256 {
static func hash(data: Data) -> Data? {
var hash = [UInt8](repeating: 0, count: Int(CC_SHA256_DIGEST_LENGTH))
data.withUnsafeBytes {
_ = CC_SHA256($0.baseAddress, CC_LONG(data.count), &hash)
}
return hexFrom(Data(hash)).lowercased(with: .current).data(using: .utf8)
}

static func hexFrom(_ data: Data) -> String {
let midpoint = data.count / 2
return data[..<midpoint].map { String(format: "%02lX", UInt($0)) }.joined()
}
}
}

parfeon marked this conversation as resolved.
Show resolved Hide resolved
/// An Error returned from a `Crypto` function
public enum CryptoError: CCCryptorStatus, Error, LocalizedError {
/// Insufficent buffer provided for specified operation.
Expand Down
Loading