Using NSStream and Secure Sockets

RogerHardimanRogerHardiman GBMember ✭✭
edited August 2015 in Xamarin.iOS

Hi
I need some help with Secure Sockets in Xamarin iOS when using NSStream socket connections.

(I originally wrote code using .Net socket classes and TLS. Works well but get periodic pauses in the data received so am trying NSStream)

I've had a go at implementing my iOS socket code in Xamarin using NSStream. This code is more or less like this...

CFStream.CreatePairWithSocketToHost(hostname,port, out cfRead, out cfWrite);
// Toll-Free binding from CFStream to a NSStream.
inStream =  (NSInputStream)ObjCRuntime.Runtime.GetNSObject(cfRead.Handle);
outStream = (NSOutputStream)ObjCRuntime.Runtime.GetNSObject(cfWrite.Handle);
// Make Secure using TLS (not using SSL any more)
inStream.SocketSecurityLevel = NSStreamSocketSecurityLevel.TlsV1;
outStream.SocketSecurityLevel = NSStreamSocketSecurityLevel.TlsV1;
// Wire up handler
inStream.OnEvent += (object sender, NSStreamEventArgs e) => {
    Console.WriteLine("InStream: Event "+e.StreamEvent.ToString());
    // Handle connection, error and data available messages
}
// connect to custom runloop (extracted from a native iOS thread
inStream.Schedule(myThread.GetRunLoop(), NSRunLoop.NSDefaultRunLoopMode);  // use our own runloop
outStream.Schedule(myThread.GetRunLoop(), NSRunLoop.NSDefaultRunLoopMode); // use our own runloop
// Connect
inStream.Open();
outStream.Open();

This code will make a Secure connection (TLS) to my server with a proper signed certificate.
Now I need to connect to a server with a self generated certificate. The project is aware of the risks.

I have read this can be done using CFStream and a Dictionary

    NSDictionary *settings = [[NSDictionary alloc] initWithObjectsAndKeys:
    [NSNumber numberWithBool:YES], kCFStreamSSLAllowsExpiredCertificates,
    [NSNumber numberWithBool:YES], kCFStreamSSLAllowsAnyRoot,
    [NSNumber numberWithBool:NO], kCFStreamSSLValidatesCertificateChain,
    kCFNull,kCFStreamSSLPeerName,
    nil];
    CFReadStreamSetProperty((CFReadStreamRef)inStream, kCFStreamPropertySSLSettings, (CFTypeRef)settings);
    CFWriteStreamSetProperty((CFWriteStreamRef)outStream, kCFStreamPropertySSLSettings, (CFTypeRef)settings);

How do I port this Dictionary code to Xamarin.iOS. Just cannot figure it out.

Any ideas?

Thanks
Roger

Posts

  • adamkempadamkemp USInsider, Developer Group Leader mod

    I think you want this method.

  • RogerHardimanRogerHardiman GBMember ✭✭

    Hi @adamkemp . Thanks for the post.
    The DoSetProperty method is protected so I don't know how to call it.
    Also Xamarin does not define any of the kCFStream constants in any form of C# enum or string that I could find so not sure how to use this method.

    Thanks
    Roger

  • adamkempadamkemp USInsider, Developer Group Leader mod

    NSStream has a [] operator so you can treat it like a dictionary:

    var value = inStream[key];
    

    I couldn't find a binding for that constant, but it looks like you could do this:

    var key = ObjCRuntime.Dlfcn.GetStringConstant("kCFStreamPropertySSLSettings", Libraries.CoreFoundation.Handle);
    

    I haven't tried this, but it seems like a direction that might work.

Sign In or Register to comment.