Cocoaphony

RNCryptor and My Titanium Experiment

Several months ago, I received a request to port my RNCryptor module to Titanium. I’ve never been a fan of the JavaScript wrappers for iOS and Android. My belief and experience is that they’re far more trouble than their worth. But the goal of RNCryptor was always to help people use AES correctly, and that’s as important in JavaScript as it is in Objective-C. So I wrapped up RNCyptor into a Titanium module and stuck it on the Appcelerator Marketplace. Though RNCryptor is free, the pain of wrapping it into JavaScript led me to charge $10 for the Titanium version.

The pain of maintaining this thing has gotten to be too much, though. I’m releasing it today on GitHub in its current form, which is based on the older, synchronous form of RNCryptor. I may not have updated all the license text yet; if I miss any, it is under the MIT license. Thanks to those who purchased Cryptor-Titanium during its commercial life. Anyone who is interested in continuing development, please contact me (or submit a pull request).

Updated RNCryptor

I have brought the RNCryptor async branch to master. This is a major change in API, but I believe much more flexible. I’ve stripped the API down quite a lot, so please let me know if there are missing features. I’m particularly interested in anyone who needs better support for reading and writing files. I haven’t added any methods for that until I see how people are really using it.

Phone-screening Cocoa Developers

There was an interesting question on StackOverflow that was unfortunately closed as off topic. It was off topic, but it’s still a useful question. When phone screening potential Cocoa developers, what kinds of questions should you ask? I’ve helped several clients screen potential candidates over the years, and so I have several questions I use to help with that.

RNCryptor Async

I have completed the major work for RNCryptor asynchronous operations on the async branch. This changes the API and the file format. I’ll be documenting this more formally within a few weeks, but here are the high points:

Mode Changes for RNCryptor

After several feature requests, much consideration, and a long chat with the security engineering team at Apple, I’ve decided to make a change to the default AES mode used by RNCryptor from its current CTR to the much more ubiquitous CBC.

CTR mode has several advantages that I was hoping to exploit. First, it does not require padding, so it is not subject to padding oracle attacks (the cipher text is also generally a few bytes shorter than the equivalent CBC). That said, if the same nonce+counter+key combination is ever reused, an attacker can easily compute the key. This is pretty unlikely given how RNCryptor generates its nonce, but it’s not impossible. If the same IV+key is used for CBC mode, then some information is leaked to an attacker, but its not nearly as catastrophic as reusing a nonce. The point is that CTR is not a home run here. It’s different, exchanging one possible vulnerability for a different one (since RNCryptor does not store previous nonces to prevent reuse).

It is also possible to compute CTR in parallel on multiple cores. Apple doesn’t currently do this, and is not highly likely to do so in the future. They might, but it’s not something to adapt the design to.

Almost every AES system out there implements CBC, so using any other mode introduces a significant interoperability problem. A mode would need to be dramatically better to be worth that. CTR has not lived up to that requirement, and so I’m switching to CBC.

This will make it much easier to write RNCryptor-compatible modules in Java, JavaScript, etc., as have been requested.

Possibly most importantly, this change gets us closer to making RNCryptor compatible back to iOS 4.0, and Mac OS X 10.4. I still have to consider CCKeyDerivationPBKDF.

If you update, note that this is incompatible with your existing encrypted files. I doubt there is enough field usage out there that this is an issue, but if it is, let me know and I can discuss with you how to convert.

Simple GCD Timer (RNTimer)

I know this exists out there somewhere already, but I couldn’t find it anywhere and I was sick of writing it over and over again…. If someone knows of previous art, please point me in the right direction. I know Fiery Robot’s and Mike Ash’s, but they solve different problems.

Have you ever noticed how hard it is to write a repeating NSTimer that doesn’t create a retain loop? Almost always you wind up with something like this:

[NSTimer scheduledTimerWithTimeInterval:1
                                 target:self
                               selector:@selector(something)
                               userInfo:nil 
                                repeats:YES];

Seems easy enough, except it’s a retain loop. Mike Ash does a nice job of explaining it and walking you through the hoops you need to avoid it. For such a common thing, you’d think this would be easy. And it should be, so I fixed it. I just still can’t quite believe I’m the first to do so.

Anyway, for your consideration I present a very simple class called RNTimer. Right now it just handles the most common case: a repeating timer that does not generate a retain loop and automatically invalidates when it is released. It could of course be expanded to handle more NSTimer functionality if there is interest. Let me know if you have a use case that the current implementation doesn’t address.

You may find it along with further information at GitHub.

Wrapping C++ Final Edition

I have always strong recommended segregating Objective-C and C++ code with a thin Objective-C++ wrapper. I do not like Objective-C++. It is useful for what it does, but it is a mess of a “language.” It has many downsides, for slower compiles and poor debugging facilities, to confusing code and inefficient ARC code. .mm is a blight on your code. Never let it spread.

That said, Objective-C++ is invaluable for integrating C++ into Objective-C. And while I am not a great lover of C++, it is a very useful language and there is a great deal of excellent code written in it that is well-worth reusing in your Cocoa projects. Many of Apple’s frameworks are implemented in C++.

So my recommendation for those who have existing C++ logic code has always been thus: write your UI in pure Objective-C (.m). Write your “middleware” in pure C++ (.cpp). And have a thin Objective-C++ (.mm) wrapper layer to glue them together. Your ObjC++ API should ideally exactly match your C++ API, just converting types (for instance converting std::string to and from NSString).

Github and Its Pricing

I’ve been looking into better ways to host my repositories for clients, manage task lists, documents, etc. I like github. It’s a good interface. It works. I could use a few more features in the Issues module, but it’s nice that they keep it simple. I’ve tried BitBucket and Assembla, and looked at several others. I’ve managed my own servers. In every test, github wins.

Except for price. github is often the most expensive. Especially if you need what I need, which is several small repositories, each with a small number of collaborators (often just one or two). But just a few of those can push you into the Medium plan, or even into the Bronze plan.