How to connect using Socket-IO-Swift on a self-signed certificate? - ios

I use the framework Socket.IO-cleint-swift. Below is the code for creating and connecting:
let socket = SocketIOClient.init(socketURL: URL(string: "https://ts4.steelsea.net:8080")!, config: [.log(true), .forcePolling(true),.secure(true),.selfSigned(true)])
socket.on("connect") {data, ack in
print("socket connected")
}
socket.on("currentAmount") {data, ack in
if let cur = data[0] as? Double {
socket.emitWithAck("canUpdate", cur).timingOut(after: 0) {data in
socket.emit("update", ["amount": cur + 2.50])
}
ack.with("Got your currentAmount", "dude")
}
}
socket.connect()
Below is an error:
ERROR SocketIOClient: The certificate for this server is invalid. You
might be connecting to a server that is pretending to be
“ts4.steelsea.net” which could put your confidential information at
risk.
I can not figure out how to confirm this certificate to me.

This is connected with insecure connection with the server. And that is why Socket.IO is sending you error.
If you would like to silent this error you can try to drop secure(true) and selfSigned(true) configs.

Related

Why I can't access my nodejs local server from iOs simulator

I am trying to make an http request from my xcode to my local server running on nodejs. The following in a part of my iOs code.
let url = URL(string: "http://localhost.com/signup")!
let task = URLSession.shared.dataTask(with: url) {(data, response, error) in
guard let data = data else { return }
print(String(data: data, encoding: .utf8)!)
}
task.resume()
I recieve the following the response
Error Domain=NSURLErrorDomain Code=-1001 "The request timed out."
Error Domain=NSURLErrorDomain Code=-1003 "A server with the specified hostname could not be
found.
I receive the first error if I use localhost.com and I receive the second error if I change the request to www.localhost.com
in this case you have to use your IP to get access to your localhost
ex: let url = URL(string: "http://192.168.1.105/signup")!
so Instead of using (localhost.com/...) you have to set the IP of your computer where you have LOCAL SERVER.

iOS: SSL Handshake over bluetooth

I'm trying to do a SSL Handshake over Bluetooth. I've been trying to use the Secure Transport API (https://developer.apple.com/documentation/security/secure_transport) to achieve this:
func sslHandshake() {
guard let sslContext = SSLCreateContext(kCFAllocatorDefault, .clientSide, .streamType) else {
return
}
SSLSetIOFuncs(sslContext, { (connection, data, dataLength) -> OSStatus in
//Read
return noErr
}) { (connection, data, dataLength) -> OSStatus in
//Write
writeToPeripheral(data)
return noErr
}
SSLHandshake(sslContext)
}
I've been able to write the client hello data to the bluetooth peripheral without a problem. But before I can write the server hello that I get from the peripheral, the SSL handshake fails and when I try doing a SSLRead I get an error -9806.
Is there a way I can avoid the handshake from failing so I can write the server hello, cert and other stuff for the handshake?

swift - I can connect to socket.io server but I can't emit event

I am beginner to socket.io
now I can connect to socket server & server log my connection
but I can't emit events to the server
here is my code :
let socket = SocketIOClient(socketURL: URL(string: "http://xxxxxxx:3000")!)
socket.connect()
let username = "yay"
socket.emit("add", username)
finally i solved the problem :
socket.on("connect")
{data, ack in
print("socket connected")
socket.emit("chat message",myJSON)
}

Connect to local mac server from device

Im trying to connect to a ruby sinatra server that im running locally on my mac from an app using the following code:
func load(finished: #escaping ()->()) {
// Create destination URL
let destinationFileUrl = documentsUrl.appendingPathComponent("Images.zip")
//Create URL to the source file you want to download
let fileURL = URL(string: "http://waynerumble.local~waynerumble:4567/download")
//Create Session
let sessionConfig = URLSessionConfiguration.default
let session = URLSession(configuration: sessionConfig)
let request = URLRequest(url:fileURL!)
let task = session.downloadTask(with: request) { (tempLocalUrl, response, error) in
if let tempLocalUrl = tempLocalUrl, error == nil {
// Success
if let statusCode = (response as? HTTPURLResponse)?.statusCode {
print("Successfully downloaded. Status code: \(statusCode)")
}
do {
try FileManager.default.copyItem(at: tempLocalUrl, to: destinationFileUrl)
} catch (let writeError) {
print("Error creating a file \(destinationFileUrl) : \(writeError)")
}
finished()
} else {
print("Error took place while downloading a file. Error description: %#", (error?.localizedDescription)! as String);
finished()
}
}
task.resume()
}
If i test the app from the simulator and set the fileURL to "http://127.0.0.1:4567/download" it works fine but from device i understand this has to be different so far I've tried:
From running ifconig in terminal i get 192.168.1.254 at en1 so i tried "http://192.168.1.255:4567/download" which gave me:
[] nw_socket_connect connectx failed: [13] Permission denied
Error took place while downloading a file. Error description: %# Could not connect to the server.
Ive also tried:
"http://waynerumble.local:4567/download" which gives:
Error took place while downloading a file. Error description: %# Could not connect to the server.
"http://waynerumble.local.~waynerumble:4567/download"(waynerumble is my computer name and username) which gives:
Error took place while downloading a file. Error description: %# A server with the specified hostname could not be found.
I also have wifi internet sharing on from both ethernet and iphone. Im not sure what else to try
192.168.1.255 is a brodcast adress for your network and you should not use it.
Why dont you connect to your real IP 192.168.1.254?
To bind Sinatra app to every interface try:
class MyApp < Sinatra::Base
set :bind, '0.0.0.0'
Then http://192.168.1.254:4567/download should work.
Also remember about opening desired port in the firewall.

Swift 3 How to validate server certificate using SSL Pinning and AlamoFire?

I'm writing an app in swift 3 that needs to talk to my server. I have the full certificate chain in der and crt format which I am the CA for(Not to be confused with self signed). How do I use this in my app to validate my server? Below is my rest call and response
Rest Call:
var request = URLRequest(url: URL(string: "https://myserver/login")!)
request.addValue("Content-Type", forHTTPHeaderField: "application/json")
request.httpMethod = "GET"
let session = URLSession.shared
session.dataTask(with: request) {data, response, err in
print("=========================DATA===============================")
if data != nil {
print(data!)
}
print("=========================RESPONSE===============================")
if response != nil {
print(response!)
}
print("=========================ERR===============================")
if err != nil {
print(err!)
}
}.resume()
Output:
=========================DATA===============================
=========================RESPONSE===============================
=========================ERR===============================
Error Domain=NSURLErrorDomain Code=-1200 "An SSL error has occurred and a secure connection to the server cannot be made." UserInfo={NSURLErrorFailingURLPeerTrustErrorKey=<SecTrustRef: 0x60800011f020>, NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9802, NSErrorPeerCertificateChainKey=(
"<cert(0x7fae4803d200) s: myserver i: MySubCA>",
"<cert(0x7fae48047000) s: MySubCA i: MyRootCA>",
"<cert(0x7fae48044600) s: MyRootCA i: MyRootCA>"
), NSUnderlyingError=0x60800005a040 {Error Domain=kCFErrorDomainCFNetwork Code=-1200 "(null)" UserInfo={_kCFStreamPropertySSLClientCertificateState=0, kCFStreamPropertySSLPeerTrust=<SecTrustRef: 0x60800011f020>, _kCFNetworkCFStreamSSLErrorOriginalValue=-9802, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9802, kCFStreamPropertySSLPeerCertificates=(
"<cert(0x7fae4803d200) s: myserver i: MySubCA>",
"<cert(0x7fae48047000) s: MySubCA i: MyRootCA>",
"<cert(0x7fae48044600) s: MyRootCA i: MyRootCA>"
)}}, NSLocalizedDescription=An SSL error has occurred and a secure connection to the server cannot be made., NSErrorFailingURLKey=https://myserver/login, NSErrorFailingURLStringKey=https://myserver/login, NSErrorClientCertificateStateKey=0}
I solved it pretty simply leveraging an online blog, AlamoFire and openssl.
I used AlamoFire for the networking on iOS.
I used an article about SSL pinning on iOS to get on the right direction.
I used openssl to convert my cert to der format.
Der conversion through openssl.
openssl x509 -in cert.crt -out cert.der -outform DER
You will need to add the der formatted cert to your app bundle.
Swift 3 implementation
// Your hostname and endpoint
let hostname = "YOUR_HOST_NAME"
let endpoint = "YOUR_ENDPOINT"
let cert = "YOUR_CERT" // e.g. for cert.der, this should just be "cert"
// Set up certificates
let pathToCert = Bundle.main.path(forResource: cert, ofType: "der")
let localCertificate = NSData(contentsOfFile: pathToCert!)
let certificates = [SecCertificateCreateWithData(nil, localCertificate!)!]
// Configure the trust policy manager
let serverTrustPolicy = ServerTrustPolicy.pinCertificates(
certificates: certificates,
validateCertificateChain: true,
validateHost: true
)
let serverTrustPolicies = [hostname: serverTrustPolicy]
let serverTrustPolicyManager = ServerTrustPolicyManager(policies: serverTrustPolicies)
// Configure session manager with trust policy
afManager = SessionManager(
configuration: URLSessionConfiguration.default,
serverTrustPolicyManager: serverTrustPolicyManager
)
afManager.request(endpoint, method: .get).responseJSON { response in
debugPrint("All Response Info: \(response)")
}

Resources