Structure and Interpretation of Computer Programmers

I make it easier and faster for you to write high-quality software.

Tuesday, December 27, 2011

These things are hard

Mike Lee recently wrote about his feelings on seeing those classic pictures from the American space program, in which the earth appears as a small blue marble set against the backdrop of space. His concluding paragraph:

Life has its waves. There are ups and downs. My not insubstantial gut and my lucky stars both are telling me 2012 is going to be an upswell. Let us do as we do where I grew up and catch that wave. Put aside your fear and cynicism. The future is ours to create. The system is ours to debug and refactor.

For me, the most defining and inspiring moment of the whole space program predates the Space Shuttle, the moon landing, even the Gemini program. It is the words of a politician, driving his country to one of its highest ebbs of innovation and discovery. The whole speech is worth watching, but this sentence encapsulates the sentiment perfectly.

We choose to go to the moon in this decade and do the other things, not because they are easy, but because they are hard, because that goal will serve to organize and measure the best of our energies and skills, because that challenge is one that we are willing to accept, one we are unwilling to postpone, and one which we intend to win, and the others, too.

So let us create the future. It is not going to be easy, but we shall choose to do it because it is hard.

posted by Graham at 14:09  

Saturday, December 17, 2011

On explaining stuff to people

An article that recently made the rounds, though it was written back in September, is called Apple’s Idioten Vektor. It’s a discussion of how the CCCrypt() function in Apple’s CommonCrypto library, when used in its default cipher block chaining mode, treats the IV (Initialization Vector) parameter as optional. If you don’t supply an IV, it provides its own IV of 0x0.

Professional Cocoa Application Security also covers CommonCrypto, CBC mode, and the Initialization Vector. Pages 79-88 discuss block encryption. The section includes sample code for both one-shot and staged use of the API. It explains how to set the IV using a random number generator, and why this should be done.[1] Mercifully when the author of the above blog post reviewed the code in my book section, he decided I was doing it correctly.

So both publications cover the same content. There’s a clear difference in presentation technique, though. I realise that the blog post is categorised as a “rant” by the author, and that I’m about to be the pot that calls the kettle black. However, I do not believe that the attitude taken in the post—I won’t describe it, you can read it—is constructive. Calling people out is not cool, helping them get things correct is. Laughing at the “fail” is not something that endears people to us, and let’s face it, security people could definitely be more endearing. We have a difficult challenge: we ask developers to do more work to bring their products to market, to spend more money on engineering (and often consultants), in return for potentially protecting some unquantified future lost revenue and customer hardship.

Yes there is a large technical component in doing that stuff, but solving the above challenge also depends very strongly on relationship management. Security experts need to demonstrate that we’re all on the same side; that we want to work with the rest of the software industry to help make better software. Again, a challenge arises: a lot of the help provided by security engineers comes in the form of pointing out mistakes. But we shouldn’t be self promoting douchebags about it. Perhaps we’re going about it wrong. I always strive to help the developers I work with by identifying and discussing the potential mistakes before they happen. Then there’s less friction: “we’re going to do this right” is a much more palatable story than “you did this wrong”.

On the other hand, the Idioten Vektor approach generated a load of discussion and coverage, while only a couple of thousand people ever read Professional Cocoa Application Security. So there’s clearly something in the sensationalist approach too. Perhaps it’s me that doesn’t get it.

[1]Note that the book was written while iPhone OS 3 was the current version, which is why the file protection options are not discussed. If I were covering the same topic today I would recommend eschewing CCCrypto for all but the most specialised of purposes, and would suggest setting an appropriate file protection level instead. The book also didn’t put encryption into the broader context of cryptographic protocols; a mistake I have since rectified.

posted by Graham at 00:33  

Wednesday, December 7, 2011

On SSL Pinning for Cocoa [Touch]

Moxie Marlinspike, recently-acquired security boffin at Twitter, blogged about SSL pinning. The summary is that relying on the CA trust model to validate SSL certificates introduces some risk into using an app – there are hundreds of trusted roots in an operating system like iOS, and you don’t necessarily want to trust all (or even any) of the keyholders. Where you’re connecting to a specific server under your control, you don’t need anyone else to tell you the server’s identity: you know what server you need to use, you should just look for its certificate. Then it doesn’t matter if someone compromises any CA; you’re not trusting the CAs any more. He calls this SSL pinning, and it’s something I’ve recommended to Fuzzy Aliens clients over the past year. I thought it’d be good to dig into how you do SSL pinning on Mac OS X and iOS.

The first thing you need to do is to tell Foundation not to evaluate the server certificate itself, but to pass the certificate to you for checking. You do this by telling the NSURLConnection that its delegate can authenticate in the “server trust” protection space.

-(BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)space {
  return [[space authenticationMethod] isEqualToString: NSURLAuthenticationMethodServerTrust];

Now your NSURLConnection delegate will receive an authentication challenge when the SSL connection is negotiated. In this authentication challenge, you evaluate the server trust to discover the certificate chain, then look for your certificate on the chain. Because you know exactly what certificate you’re looking for, you can do a bytewise comparison and don’t need to do anything like checking the common name or extracting the fingerprint: it either is your certificate or it isn’t. In the case below, I look only at the leaf certificate, and I assume that the app has a copy of the server’s cert in the sealed app bundle at

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
  if ([[[challenge protectionSpace] authenticationMethod] isEqualToString: NSURLAuthenticationMethodServerTrust]) {
    SecTrustRef serverTrust = [[challenge protectionSpace] serverTrust];
    (void) SecTrustEvaluate(serverTrust, NULL);
    NSData *localCertificateData = [NSData dataWithContentsOfFile: [[NSBundle mainBundle]
                                                                    pathForResource: serverName
                                                                    ofType: @"cer"]];
    SecCertificateRef remoteVersionOfServerCertificate = SecTrustGetCertificateAtIndex(serverTrust, 0);
    CFDataRef remoteCertificateData = SecCertificateCopyData(remoteVersionOfServerCertificate);
    BOOL certificatesAreTheSame = [localCertificateData isEqualToData: (__bridge NSData *)remoteCertificateData];
    if (certificatesAreTheSame) {
      [[challenge sender] useCredential: [NSURLCredential credentialForTrust: serverTrust] forAuthenticationChallenge: challenge];
    else {
      [[challenge sender] cancelAuthenticationChallenge: challenge];
  // fall through for challenges in other spaces - or respond to them if you need to

That’s really all there is to it. You may want to change some of the details depending on your organisation: for example you may issue your own intermediate or root certificate and check for its presence while allowing the leaf certificate to vary; however the point is to get away from the SSL certificate authority trust model so I haven’t shown that here.

posted by Graham at 17:33  

Friday, December 2, 2011

A bunch of monkeys with typewriters

As with many of the posts in this blog, this one originally started as a tweet that got too long. With the launch of Path 2, a conversation about Atos ditching email for social media and Yammer posting a video of how their enterprise social network is used at O2, I’ve been thinking about how I’d design the social network for business users.

The TL;DR (or executive summary, if that’s your thing) is “don’t be a lazy arse, read the whole post”.


Computer-Supported Collaborative Working. A term that has been around for a few decades, and means pretty much what it says: finding ways to use computers to support people working together. Ideas from CSCW pervade the modern requirements engineering discipline; particularly strong is the notion that the software and the system in which it’s used are related. Change the software and you’ll change the way people work together. Change the people and you’ll change the way they work together too, including how they use the software.

When I finished being an undergraduate and became an actual person, real-world CSCW was synonymous with “groupware” and basically meant an email service with integrated calendars. Wikis existed, and some companies were using them. Trouble ticket systems like req and rt did exist too. All of these tools were completely separate. Most of them, if they needed to tell you something, would send you an email.

Ah, email. The tool that changed “read your memos at 4:30 pm” into a permanent compulsion. How that big red badge on your mail icon taunts you, with its message that there are now THREE REALLY IMPORTANT THINGS you’re ignoring. Only one’s a message from facilities telling you that the wastepaper baskets have been moved, and while the other two are indeed task-related they carry no new information (“I agree we should touch base to talk around this action”). Originally the red badge only mocked me while I was in the office, but then I was issued a smartphone.

Email: the tool that makes conversations in other parts of the company completely undiscoverable. You can no longer get a feel for what’s going on by hanging around the water cooler or the smokers’ shelter, because those discussions are being held over email. Email that you can only read if you’re in on the joke. If you’re supposed to be in on the joke but the author addresses her missive to “j.smith3” instead of “j.smith1”, you’re shit out of luck. Email where you have to look at whether you were CCd or BCCd before weighing in with your tuppen’orth.

We’ve come a long way baby

OK, since those dark days we’ve learned a lot, right? There’s Twitter, and Facebook, and Myspace (yes, it is still a thing), and LinkedIn and Path and Tumblr and Glassboard and…

Lots of these things have good ideas, and lots have not so good ideas. Most of them are designed to be very general things that people in many contexts would use: what would a (by which I mean “my”) business-centric comms tool designed today look like?

The features

Completely replaces internal e-mail for everyone

This is non-negotiable. No more multiple channels of communication (I currently have open: twitter, outlook, skype and IRC. And I’m writing a blog post. And I have a phone. And I get Path push notifications.). No more trying to match up threads that have come in and out of various applications. If the CEO wants to leave a message for the CTO, he does it over the social network, just as when one of the cleaners wants to talk to another.

Pull, don’t push

I will say this nice and loud: I don’t care when your shitty app thinks I need to read my messages. I have work to do, let me get on with it without the guilt of the red badge. Support an OmniFocus-style view where I can see what’s come in, what’s outstanding, and what I think is important or urgent. But let me review that on my own terms. I don’t care whether the personal assistant of the head of some other department thinks this message is double-exclamation-mark-urgent; I’ll decide. Let me set up notifications on things I think important to be notified about.

Everything is a citable object

Twitter gets this correct, facebook does not. Except that Twitter doesn’t really, because I can’t really write long-form posts, styled posts, or put images/video/audio/etc. in Tweets. I can just pretend using URLs. But it does allow you to treat a reply as a first-class object: it’s just a tweet that has a link to a previous tweet. In facebook, comments are special things that are attached to other things but don’t really have an existence of their own.

Facebook also decides that different ways of communicating with someone are, for some reason, different things. Notes appear in the “notes” section, updates on the wall (including updates that are links to notes), photos in photos, music in…you get the idea. I say the important things are who said what to whom, and in what context. If I want to write a long-form post about a comment that was a reply to a photo posted in response to a customer service request, I should be able to do that. That implies that our hypothetical social network would be a platform that can support applications like request tracking, bug reporting, CRM and whatever else it is that people in a big company do. Which brings me on to the next two features.

I need to be able to discover people

People (indeed any primates) naturally organise into smallish close groups, in which they understand the dyads (what each people thinks about the others) quite well. They then know a little bit about what the other groups are, but not necessarily about the relationships inside those groups. Current social network tools don’t really take advantage of that: and no, Google+ circles are not this.

Companies, in fact, do not take this into account. Hierarchical management structures lead to an easy identification of “us” and “them”, so that whenever someone in a different group causes “us” to re-think what we’re doing, we assume that “they” don’t get what “we” are all about. We’re all trying to make the same shareholders rich (or change the world, or gain a pension; whyever it is you do what you do) and we should all be on the same side.

If I’m looking for someone in Legal who knows about open source licenses, the tool should support that. Furthermore, the tool should show me how their circle overlaps with mine, so I can see who to go to (and who to avoid) for an introduction if that’s the best way to proceed. The chance is that in a company with thousands of employees I don’t know who I’m looking for, but someone I know does know. Furthermore, the tool should be able to use sentiment analysis to tell whether the people I’m going to talk to are likely to be on my side or not. This should help combat the “us vs. them” mentality described above, because I can go into my new meeting knowing where I’m similar to my new contact.

[An early draft of the section you’ve just read was titled “It isn’t who you know, it’s who you know who you know knows” but that wasn’t really the name of a feature.]

There are no silos or Chinese walls: everyone can see (and react to) everything.

This has a few benefits. Most importantly, this is a time where valuable advances are being made not by gathering information – which we’ve been doing for decades – but by finding new ways of combining, organising and analysing the data that we’ve already got. Which makes it crazy that most companies stop people from taking a cross-functional view of the things going on in that company. It’s maddening, it costs money, and it needs to stop. If I’m doing some research into, for example, fixing some bug in a product and can find out that Jim on the team downstairs has recently been fixing a related bug on his team’s product, that’s useful. I should be able to see that: we need a platform that supports it.

The second benefit is to remove another barrier that reinforces the “us vs. them” separation of departments. No, sales aren’t hiding anything from you: it’s all available.

Next, if everyone knows that anything they say in “new email” is readable by everyone else in the company, that also helps to increase the collaborative nature of interactions because you can’t hide behind the almost-private nature of email.

Path has an interesting feature in this regard: for each event you can see, you can also see who has seen that event. It’s a useful reminder that what you write is being read, and by whom: once you’ve seen your head of department pop up a few times, you probably remember to make everything work-safe. It’s almost an implementation of the “your mum can read what you write” reminder I wanted to add to facebook.

Now I can hear my security colleagues sharpening their ePencils to write the “waah, insider threat” comment. My question is this: so? Insider threats are an HR problem, so rather than making everybody suffer by carving up the company, consider giving the HR department the tools they need to detect and react to the problem. Such as, I don’t know, a tool that provides a view on what company data people are interacting with along with sentiment analysis…

There are some things that genuinely do need to have restricted access: customer data, employee personal information and the like. These should be exceptions, not the norm, and treated exceptionally. Similarly, contractors and other suppliers who probably should be given access to the platform can have need-to-know access. Again, that doesn’t mean that all your permies do. In fact, show your permies that you trust them with the ability to see what’s going on across the whole company, you’ll probably end up with happier and more motivated permies.

All of this stuff about tearing down the walls doesn’t stop you allowing the employees to organise into groups on the platform. But such groups should be self-organising, transient, and transparent: just because I didn’t join, that doesn’t mean I shouldn’t be able to join in.

Smart searches

Final thing: if you build everything above, you’re plugging everyone in to the company firehose. Make it easy for people to find what they’re after, and to review when new matching results become available.

posted by Graham at 15:32  

Powered by WordPress