Compare commits
No commits in common. "signal-release" and "master" have entirely different histories.
signal-rel
...
master
@ -80,12 +80,10 @@ class Decompressor {
|
||||
strm.avail_in = CUnsignedInt(count)
|
||||
|
||||
repeat {
|
||||
buffer.withUnsafeMutableBytes { (bufferPtr) in
|
||||
strm.next_out = bufferPtr.bindMemory(to: UInt8.self).baseAddress
|
||||
strm.avail_out = CUnsignedInt(bufferPtr.count)
|
||||
strm.next_out = UnsafeMutablePointer<UInt8>(&buffer)
|
||||
strm.avail_out = CUnsignedInt(buffer.count)
|
||||
|
||||
res = inflate(&strm, 0)
|
||||
}
|
||||
res = inflate(&strm, 0)
|
||||
|
||||
let byteCount = buffer.count - Int(strm.avail_out)
|
||||
out.append(buffer, count: byteCount)
|
||||
@ -144,12 +142,10 @@ class Compressor {
|
||||
strm.avail_in = CUnsignedInt(data.count)
|
||||
|
||||
repeat {
|
||||
buffer.withUnsafeMutableBytes { (bufferPtr) in
|
||||
strm.next_out = bufferPtr.bindMemory(to: UInt8.self).baseAddress
|
||||
strm.avail_out = CUnsignedInt(bufferPtr.count)
|
||||
strm.next_out = UnsafeMutablePointer<UInt8>(&buffer)
|
||||
strm.avail_out = CUnsignedInt(buffer.count)
|
||||
|
||||
res = deflate(&strm, Z_SYNC_FLUSH)
|
||||
}
|
||||
res = deflate(&strm, Z_SYNC_FLUSH)
|
||||
|
||||
let byteCount = buffer.count - Int(strm.avail_out)
|
||||
compressed.append(buffer, count: byteCount)
|
||||
|
||||
@ -149,10 +149,7 @@ open class SSLSecurity : SSLTrustValidator {
|
||||
} else {
|
||||
policy = SecPolicyCreateBasicX509()
|
||||
}
|
||||
guard SecTrustSetPolicies(trust, policy) == errSecSuccess else {
|
||||
assertionFailure("unable to set trust policies")
|
||||
return false
|
||||
}
|
||||
SecTrustSetPolicies(trust,policy)
|
||||
if self.usePublicKeys {
|
||||
if let keys = self.pubKeys {
|
||||
let serverPubKeys = publicKeyChain(trust)
|
||||
@ -170,15 +167,9 @@ open class SSLSecurity : SSLTrustValidator {
|
||||
for cert in certs {
|
||||
collect.append(SecCertificateCreateWithData(nil,cert as CFData)!)
|
||||
}
|
||||
guard SecTrustSetAnchorCertificates(trust, collect as NSArray) == errSecSuccess else {
|
||||
assertionFailure("unable to set trust anchor certificates")
|
||||
return false
|
||||
}
|
||||
SecTrustSetAnchorCertificates(trust,collect as NSArray)
|
||||
var result: SecTrustResultType = .unspecified
|
||||
guard SecTrustEvaluate(trust, &result) == errSecSuccess else {
|
||||
assertionFailure("unable to evaluate trust")
|
||||
return false
|
||||
}
|
||||
SecTrustEvaluate(trust,&result)
|
||||
if result == .unspecified || result == .proceed {
|
||||
if !validateEntireChain {
|
||||
return true
|
||||
@ -222,17 +213,11 @@ open class SSLSecurity : SSLTrustValidator {
|
||||
*/
|
||||
public func extractPublicKey(_ cert: SecCertificate, policy: SecPolicy) -> SecKey? {
|
||||
var possibleTrust: SecTrust?
|
||||
guard SecTrustCreateWithCertificates(cert, policy, &possibleTrust) == errSecSuccess else {
|
||||
assertionFailure("failed to create trust with certificate")
|
||||
return nil
|
||||
}
|
||||
SecTrustCreateWithCertificates(cert, policy, &possibleTrust)
|
||||
|
||||
guard let trust = possibleTrust else { return nil }
|
||||
var result: SecTrustResultType = .unspecified
|
||||
guard SecTrustEvaluate(trust, &result) == errSecSuccess else {
|
||||
assertionFailure("failed to evaluate trust")
|
||||
return nil
|
||||
}
|
||||
SecTrustEvaluate(trust, &result)
|
||||
return SecTrustCopyPublicKey(trust)
|
||||
}
|
||||
|
||||
|
||||
@ -49,7 +49,6 @@ public enum ErrorType: Error {
|
||||
case protocolError //There was an error parsing the WebSocket frames
|
||||
case upgradeError //There was an error during the HTTP upgrade
|
||||
case closeError //There was an error during the close (socket probably has been dereferenced)
|
||||
case osError // There was an error with the underlying OS
|
||||
}
|
||||
|
||||
public struct WSError: Error {
|
||||
@ -70,7 +69,6 @@ public protocol WebSocketClient: class {
|
||||
#else
|
||||
var security: SSLTrustValidator? {get set}
|
||||
var enabledSSLCipherSuites: [SSLCipherSuite]? {get set}
|
||||
var socketSecurityLevel: StreamSocketSecurityLevel { get set }
|
||||
#endif
|
||||
var isConnected: Bool {get}
|
||||
|
||||
@ -115,7 +113,6 @@ public struct SSLSettings {
|
||||
#if os(Linux)
|
||||
#else
|
||||
public let cipherSuites: [SSLCipherSuite]?
|
||||
public var socketSecurityLevel: StreamSocketSecurityLevel
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -146,11 +143,6 @@ open class FoundationStream : NSObject, WSStream, StreamDelegate {
|
||||
|
||||
public var enableSOCKSProxy = false
|
||||
|
||||
deinit {
|
||||
inputStream?.delegate = nil
|
||||
outputStream?.delegate = nil
|
||||
}
|
||||
|
||||
public func connect(url: URL, port: Int, timeout: TimeInterval, ssl: SSLSettings, completion: @escaping ((Error?) -> Void)) {
|
||||
var readStream: Unmanaged<CFReadStream>?
|
||||
var writeStream: Unmanaged<CFWriteStream>?
|
||||
@ -174,8 +166,8 @@ open class FoundationStream : NSObject, WSStream, StreamDelegate {
|
||||
inStream.delegate = self
|
||||
outStream.delegate = self
|
||||
if ssl.useSSL {
|
||||
inStream.setProperty(ssl.socketSecurityLevel as AnyObject, forKey: Stream.PropertyKey.socketSecurityLevelKey)
|
||||
outStream.setProperty(ssl.socketSecurityLevel as AnyObject, forKey: Stream.PropertyKey.socketSecurityLevelKey)
|
||||
inStream.setProperty(StreamSocketSecurityLevel.negotiatedSSL as AnyObject, forKey: Stream.PropertyKey.socketSecurityLevelKey)
|
||||
outStream.setProperty(StreamSocketSecurityLevel.negotiatedSSL as AnyObject, forKey: Stream.PropertyKey.socketSecurityLevelKey)
|
||||
#if os(watchOS) //watchOS us unfortunately is missing the kCFStream properties to make this work
|
||||
#else
|
||||
var settings = [NSObject: NSObject]()
|
||||
@ -424,7 +416,6 @@ open class WebSocket : NSObject, StreamDelegate, WebSocketClient, WSStreamDelega
|
||||
#else
|
||||
public var security: SSLTrustValidator?
|
||||
public var enabledSSLCipherSuites: [SSLCipherSuite]?
|
||||
public var socketSecurityLevel: StreamSocketSecurityLevel = .negotiatedSSL
|
||||
#endif
|
||||
|
||||
public var isConnected: Bool {
|
||||
@ -442,6 +433,7 @@ open class WebSocket : NSObject, StreamDelegate, WebSocketClient, WSStreamDelega
|
||||
|
||||
private struct CompressionState {
|
||||
var supportsCompression = false
|
||||
var messageNeedsDecompression = false
|
||||
var serverMaxWindowBits = 15
|
||||
var clientMaxWindowBits = 15
|
||||
var clientNoContextTakeover = false
|
||||
@ -455,10 +447,6 @@ open class WebSocket : NSObject, StreamDelegate, WebSocketClient, WSStreamDelega
|
||||
private var isConnecting = false
|
||||
private let mutex = NSLock()
|
||||
private var compressionState = CompressionState()
|
||||
// `currentMessageNeedsDecompression` is not part of the `compressionState` struct
|
||||
// because currentMessageNeedsDecompression can be mutated in the read queue concurrently
|
||||
// with other `compressionState` fields being accesseed on the write queue.
|
||||
private var currentMessageNeedsDecompression = false
|
||||
private var writeQueue = OperationQueue()
|
||||
private var readStack = [WSResponse]()
|
||||
private var inputQueue = [Data]()
|
||||
@ -601,8 +589,8 @@ open class WebSocket : NSObject, StreamDelegate, WebSocketClient, WSStreamDelega
|
||||
}
|
||||
request.setValue(headerWSUpgradeValue, forHTTPHeaderField: headerWSUpgradeName)
|
||||
request.setValue(headerWSConnectionValue, forHTTPHeaderField: headerWSConnectionName)
|
||||
headerSecKey = generateWebSocketKey()
|
||||
request.setValue(headerWSVersionValue, forHTTPHeaderField: headerWSVersionName)
|
||||
headerSecKey = try! generateWebSocketKey()
|
||||
request.setValue(headerSecKey, forHTTPHeaderField: headerWSKeyName)
|
||||
|
||||
if enableCompression {
|
||||
@ -639,16 +627,16 @@ open class WebSocket : NSObject, StreamDelegate, WebSocketClient, WSStreamDelega
|
||||
/**
|
||||
Generate a WebSocket key as needed in RFC.
|
||||
*/
|
||||
private func generateWebSocketKey() throws -> String {
|
||||
let kSocketKeyByteLength = 16
|
||||
var randomData = Data(count: kSocketKeyByteLength)
|
||||
try randomData.withUnsafeMutableBytes { (bytes: UnsafeMutablePointer<UInt8>) throws -> Void in
|
||||
guard SecRandomCopyBytes(kSecRandomDefault, kSocketKeyByteLength, bytes) == errSecSuccess else {
|
||||
throw WSError(type: .osError, message: "unable to generate random bytes", code: 0)
|
||||
}
|
||||
private func generateWebSocketKey() -> String {
|
||||
var key = ""
|
||||
let seed = 16
|
||||
for _ in 0..<seed {
|
||||
let uni = UnicodeScalar(UInt32(97 + arc4random_uniform(25)))
|
||||
key += "\(Character(uni!))"
|
||||
}
|
||||
|
||||
return randomData.base64EncodedString()
|
||||
let data = key.data(using: String.Encoding.utf8)
|
||||
let baseKey = data?.base64EncodedString(options: NSData.Base64EncodingOptions(rawValue: 0))
|
||||
return baseKey!
|
||||
}
|
||||
|
||||
/**
|
||||
@ -669,16 +657,15 @@ open class WebSocket : NSObject, StreamDelegate, WebSocketClient, WSStreamDelega
|
||||
let settings = SSLSettings(useSSL: useSSL,
|
||||
disableCertValidation: disableSSLCertValidation,
|
||||
overrideTrustHostname: overrideTrustHostname,
|
||||
desiredTrustHostname: desiredTrustHostname,
|
||||
sslClientCertificate: sslClientCertificate)
|
||||
desiredTrustHostname: desiredTrustHostname),
|
||||
sslClientCertificate: sslClientCertificate
|
||||
#else
|
||||
let settings = SSLSettings(useSSL: useSSL,
|
||||
disableCertValidation: disableSSLCertValidation,
|
||||
overrideTrustHostname: overrideTrustHostname,
|
||||
desiredTrustHostname: desiredTrustHostname,
|
||||
sslClientCertificate: sslClientCertificate,
|
||||
cipherSuites: enabledSSLCipherSuites,
|
||||
socketSecurityLevel: socketSecurityLevel)
|
||||
cipherSuites: self.enabledSSLCipherSuites)
|
||||
#endif
|
||||
certValidated = !useSSL
|
||||
let timeout = request.timeoutInterval * 1_000_000
|
||||
@ -1009,9 +996,9 @@ open class WebSocket : NSObject, StreamDelegate, WebSocketClient, WSStreamDelega
|
||||
let payloadLen = (PayloadLenMask & baseAddress[1])
|
||||
var offset = 2
|
||||
if compressionState.supportsCompression && receivedOpcode != .continueFrame {
|
||||
currentMessageNeedsDecompression = (RSV1Mask & baseAddress[0]) > 0
|
||||
compressionState.messageNeedsDecompression = (RSV1Mask & baseAddress[0]) > 0
|
||||
}
|
||||
if (isMasked > 0 || (RSVMask & baseAddress[0]) > 0) && receivedOpcode != .pong && !currentMessageNeedsDecompression {
|
||||
if (isMasked > 0 || (RSVMask & baseAddress[0]) > 0) && receivedOpcode != .pong && !compressionState.messageNeedsDecompression {
|
||||
let errCode = CloseCode.protocolError.rawValue
|
||||
doDisconnect(WSError(type: .protocolError, message: "masked and rsv data is not currently supported", code: Int(errCode)))
|
||||
writeError(errCode)
|
||||
@ -1072,7 +1059,7 @@ open class WebSocket : NSObject, StreamDelegate, WebSocketClient, WSStreamDelega
|
||||
len -= UInt64(size)
|
||||
}
|
||||
let data: Data
|
||||
if currentMessageNeedsDecompression, let decompressor = compressionState.decompressor {
|
||||
if compressionState.messageNeedsDecompression, let decompressor = compressionState.decompressor {
|
||||
do {
|
||||
data = try decompressor.decompress(bytes: baseAddress+offset, count: Int(len), finish: isFin > 0)
|
||||
if isFin > 0 && compressionState.serverNoContextTakeover {
|
||||
@ -1263,10 +1250,7 @@ open class WebSocket : NSObject, StreamDelegate, WebSocketClient, WSStreamDelega
|
||||
}
|
||||
buffer[1] |= self.MaskMask
|
||||
let maskKey = UnsafeMutablePointer<UInt8>(buffer + offset)
|
||||
guard SecRandomCopyBytes(kSecRandomDefault, Int(MemoryLayout<UInt32>.size), maskKey) == errSecSuccess else {
|
||||
self.doDisconnect(WSError(type: .osError, message: "unable to generate random bytes", code: 0))
|
||||
return
|
||||
}
|
||||
_ = SecRandomCopyBytes(kSecRandomDefault, Int(MemoryLayout<UInt32>.size), maskKey)
|
||||
offset += MemoryLayout<UInt32>.size
|
||||
|
||||
for i in 0..<dataLength {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user