iOS swift connect TLS socket with cert per string - ios

I have created an RSA certification using a generated private/public key using this library-
https://github.com/cbaker6/CertificateSigningRequest
thanks to this library I now have a certificate in a PEM string format.
now I want to create an ssl socket that can use this certificate to connect to a remote server that requires an ssl connection.
so for example this is a pseudo code in node.js:
let options = {
key : this.certs.key,
cert: this.certs.cert,
port: this.port,
host : this.host,
rejectUnauthorized: false,
}
console.debug("Start Connect");
this.client = tls.connect(options, () => {
console.debug(this.host + " connected")
});
where the key and the cert are both a PEM string
I tried BlueSSLService lib, but they only support connecting with cert files, no strings.

Related

Sending message to azure IoT hub with x509 certificate authentication

I am trying to send telemetry messages to Azure IoT Hub using the npm mqtt library, instead of using Azure Nodejs SDK/Library.
I am using X509 certificate authentication. The device connection is working fine when I use azure Nodejs SDK/Library and I am able to send telemetry messages.
When trying to use the MQTT library, it is saying unauthorized.
const mqtt = require("mqtt");
const fs = require('fs');
let options = {
cert: fs.readFileSync("device-cert.pem", "utf-8").toString(),
key: fs.readFileSync("device-cert.key", "utf-8").toString(),
passphrase: '1234',
clientId: "device-003",
username: "ih-iot-sample-001.azure-devices.net/device-003/?api-version=2021-04-12",
}
let client = mqtt.connect(
"mqtts://ih-iot-sample-001.azure-devices.net:8883",
options
);
client.on("connect", function () {
console.log("connected");
});
client.on("error", (err) => {
console.log(err);
process.exit(0)
});
Error :
Connection refused: Not authorized
The clientid and the deviceId in the username were wrong. That's why I got this error

How to get page using client and server certificate

How to retrieve page over https using client and server certificate in .NET 6 C# ?
Using curl this works:
curl --key private.key --cert server.crt https://example.com
How to convert this to C# ?
private.key file is text file in format
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAxTvKy3WRPqli9ODpIcTb8Bhnxa2x+8xip/kWq...
server.crt is text file in format
-----BEGIN CERTIFICATE-----
MIIEnzCCAoegAwIBAgIIIJKu2MhhxF0wDQYJKoZIhvcNAQENBQAwLjEeMBwGA1UE
I tried curl to c# https://github.com/olsh/curl-to-csharp online version https://curl.olsh.me/ to convert
It throws errors
Certificate type "Pem" is not supported
Parameter "--key" is not supported
and generates code
var handler = new HttpClientHandler();
using (var httpClient = new HttpClient(handler))
using (var request = new HttpRequestMessage(new HttpMethod("GET"), "https://example.com/"))
var response = await httpClient.SendAsync(request);
Server requires private key from file private.key for authentication.
How to pass private key to server ?
This is ASP.NET 6 MVC application running in Debian.

WSS/TLS websocket connection with Swift iOS

SOLVED (following answer)
I am using Starscream library to create a safe websocket wss in the test server we have a self-signed certificate and I find it impossible to make the connection.
var socket = WebSocket(url: NSURL(scheme: "wss", host: "selfsignedserver.com", path: "/")!)
Log
2014-12-16 10:38:10.260 pruebasignin[2135:363455] CFNetwork SSLHandshake failed (-9807)
websocket is disconnected: The operation couldn’t be completed. (OSStatus error -9807.)
and when I try to connect to a server certificate valid also fails to connect
SOLVED
var socket = WebSocket(url: NSURL(scheme: "wss", host: "production.com", path: "/")!)
Log
websocket is disconnected: Invalid HTTP upgrade
Starscream now supports a flag so you can use self-signed certificates:
https://github.com/daltoniam/Starscream/blob/bf0146db269249d200bb3bc4185cb5724cfa2ae8/README.md#self-signed-ssl-and-voip
(Edited for posterity; links to the README that was published as of April 2016)
I solved the problem by allowing self-signed certificates Starscream modifying the library.
To this must be added the arcivo WebSocket.swift the following code:
if url.scheme == "wss" || url.scheme == "https" {
inputStream!.setProperty(NSStreamSocketSecurityLevelNegotiatedSSL, forKey: NSStreamSocketSecurityLevelKey)
outputStream!.setProperty(NSStreamSocketSecurityLevelNegotiatedSSL, forKey: NSStreamSocketSecurityLevelKey)
/* My code */
var settings = Dictionary<NSObject, NSObject>()
settings[kCFStreamSSLValidatesCertificateChain] = NSNumber(bool:false)
settings[kCFStreamSSLPeerName] = kCFNull
CFReadStreamSetProperty(self.inputStream, kCFStreamPropertySSLSettings, settings)
CFWriteStreamSetProperty(self.outputStream, kCFStreamPropertySSLSettings, settings)
/* End my code*/
}

node ios socket.io SSL works with xcode debug but does not with ipa install

Having node https setup
const server = require('https').createServer(
{
key: fs.readFileSync('ssl/some.key'),
cert: fs.readFileSync('ssl/some.crt')
}, handler);
iOS app performs good with xcode debug, but misses connectivity when app distributed via .ipa file.
Node https setup must include intermediate CA certificate (provided by Certificate Authority):
const server = require('https').createServer(
{
// this line is required.
ca: fs.readFileSync('ssl/intermediate.crt'),
key: fs.readFileSync('ssl/some.key'),
cert: fs.readFileSync('ssl/some.crt')
}, handler);

Uploading File Using HttpBuilder over SSL

I am attempting to upload a file to web service that is running over SSL using HttpBuilder. I'm doing this from a Gradle build file but I don't believe it really matters. The web service is part of a Grails app, but again, don't think that matters.
My grails app is running over SSL locally using a cert generated by grails when you tell it to run over https. My code that works locally is as follows:
def http = new groovyx.net.http.HTTPBuilder( 'https://localhost:8443/' )
//=== SSL UNSECURE CERTIFICATE ===
def sslContext = SSLContext.getInstance("SSL")
sslContext.init(null, [ new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {null }
public void checkClientTrusted(X509Certificate[] certs, String authType) { }
public void checkServerTrusted(X509Certificate[] certs, String authType) { }
} ] as TrustManager[], new SecureRandom())
def sf = new SSLSocketFactory(sslContext)
def httpsScheme = new Scheme("https", sf, 8443)
http.client.connectionManager.schemeRegistry.register( httpsScheme )
http.request( groovyx.net.http.Method.POST, groovyx.net.http.ContentType.JSON ) { req ->
uri.path = '/a/admin/runtime/upload'
uri.query = [ username: "username", password: "password", version: version]
requestContentType = 'multipart/form-data'
org.apache.http.entity.mime.MultipartEntity entity = new org.apache.http.entity.mime.MultipartEntity()
def file = new File("file.zip")
entity.addPart("runtimeFile", new org.apache.http.entity.mime.content.ByteArrayBody(file.getBytes(), 'file.zip'))
req.entity = entity
}
All that garbage at the top is some code I found that allows HttpBuilder to work with self signed certs. And this is actually working locally. HttpBuilder docs say that most of the time, SSL should "just work". So my code for doing this over SSL with a legit purchased certification is as follows:
def http = new groovyx.net.http.HTTPBuilder( 'https://www.realserver.com/' )
http.request( groovyx.net.http.Method.POST, groovyx.net.http.ContentType.JSON ) { req ->
uri.path = '/a/admin/runtime/upload'
uri.query = [ username: "username", password: "password" ]
requestContentType = 'multipart/form-data'
org.apache.http.entity.mime.MultipartEntity entity = new org.apache.http.entity.mime.MultipartEntity()
def file = new File("file.zip")
entity.addPart("runtimeFile", new org.apache.http.entity.mime.content.ByteArrayBody(file.getBytes(), 'file.zip'))
req.entity = entity
}
When I run this I get the following error:
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
Any tips or suggestions would be much appreciated.
This is probably because the service is using self-signed certificate for HTTPS. To interact with it correctly, you should import it to the cacerts file of your JRE using keytool. An example command looks like this:
keytool -import -alias serviceCertificate -file ServiceSelfSignedCertificate.cer -keystore {path/to/jre/lib/security/cacerts}

Resources