Skip to content

A noise protocol framework implementation in Objective-C and Swift friendly.

License

Notifications You must be signed in to change notification settings

OuterCorner/Noise

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

75 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Noise.framework

Platforms Carthage License

This project provides an macOS and iOS compatible framework to develop protocol based on the Noise Protocol Framework. It wraps the noise-c library in an easy to use object-oriented fashion.

It's written in Objective-C and is Swift friendly.

Installation

You have a few different options:

Manual installation

  • Include the Noise.xcodeproj as a dependency in your project.
  • Use a pre-built Noise.framework. You can find them under Releases.

In either case you'll also need to add the OpenSSL.framework dependency.

Carthage

Add Noise as a dependency on your Cartfile:

github "OuterCorner/Noise"

And run:

carthage update

By default Carthage will download the pre-build binaries (faster), if you want to compile from source pass --no-use-binaries to the update command above.

Usage

The public headers are extensively documented and should be fairly easy to grasp. Here's a quick overview on how to use the framework.

Start by importing the umbrella header:

// Objective-C
#import <Noise/Noise.h>
// Swift
import Noise

Noise session

The NPFSession class is central to the framework. You start by creating a session with the noise protocol you want to use:

// Objective-C
NPFSession *session = [[NPFSession alloc] initWithProtocolName:@"Noise_NK_25519_AESGCM_SHA256" role:NPFSessionRoleInitiator];
// Swift
let session = NoiseSession(protocolName: "Noise_NK_25519_AESGCM_SHA256", role: .initiator)

After that you must call setup before starting a session, even if you're using an NN handshake pattern where no setup is required:

// Objective-C
[session setup:^(id<NPFSessionSetup> setup) {
  NPFKey *pubKey = [keyManager remotePublicKeyFor:@"some responder" ofType:NPFKeyAlgoCurve25519];
  setup.remotePublicKey = pubKey;
}];
// Swift
session.setup { setup in
  let pubKey = keyManager.remotePublicKey(for: "some responder", type: .curve25519);
  setup.remotePublicKey = pubKey
}

You're now ready to start the session:

// Objective-C
NSError *error = nil;
if (![session start:&error]){
  // handle error
}
// Swift
try session.start()

After starting a session, both the sendingHandle and receivingHandle properties are ready to be bound to your transport channel. You must read from sendingHandle and send any data to your peer, be it via TCP, Unix sockets, smoke signals… Conversely any data you receive from your peer you should write to receivingHandle.

Since these are NSFileHandles you can install a readability handler to run everytime the session has data to send:

// Objective-C
session.sendingHandle.readabilityHandler = ^(NSFileHandle * fh) {
  NSData *data = [fh availableData];
  // write data to your transport channel
}
// Swift
session.sendingHandle!.readabilityHandler = { fh in
  let data = fh.availableData
  // write data to your transport channel
}

Handshake

When starting a session the first step is to perform the chosen handshake. You can either implement the delegate method -session:handshakeComplete: or observe the session s state to know when the handshake is complete.

If you're using a handshake pattern where you don't know the peer's public key beforehand, you can consult the NPFHandshakeState object passed to the delegate on handshake completion.

// Objective-C
- (void)session:(NPFSession *)session handshakeComplete:(NPFHandshakeState *)handshakeState
{
    NPFKey *remotePubKey = [handshakeState remotePublicKey]
    // do something with remotePubKey
}
// Swift
func session(_ session: NoiseSession, handshakeComplete handshakeState: NoiseHandshakeState) {
  let remotePubKey = handshakeState.remotePublicKey
  // do something with remotePubKey
}

Send and receiving messages

After the handshake is complete you can send messages via the -sendData: method and receive via the -session:didReceiveData: delegate method.

Dependencies

This projects depends on OpenSSL.framework. If you're using Carthage it will be downloaded automatically.

License

This project is licensed under the MIT License - see LICENSE.