Can You Write Good Code for an OS you Despise?

No, this isn’t another of my anti-Mac frothing rants.

This is one of my “here’s what I hate about many of the open-source projects I deal with” rants.

I’m trying to find an SFTP client for Windows that works the way I want it to.

All I seem to be able to find are SFTP clients for Unix shoe-horned in to Windows.

[Perhaps the Unix guys feel the same way about playing Halo under Wine.]

What do I mean?

Here’s an example – Windows has a certificate store. It’s well-protected, in that there haven’t been any disclosures of significant vulnerabilities that allow you to read certificates without first having got the credentials that would allow you to do so.

So, I want an SFTP client that lets me store my private keys in the Windows certificate store. Or at least, that uses DPAPI to protect its data.

Can’t find one.

Can’t find ONE. And I’m known for being good at finding stuff.

PuTTY is recommended to me. It, too, requires that the private key be stored in a file, not in the certificate store. Its alternative is to use its own certificate store, called Pageant (it’s an authorization “Age-Ant” for PuTTY, get it?) Maybe I could do something with that – write a variant of Pageant that directly accesses certificates stored in the certificate store.

But no, there’s no protocol definition or API, or service contract that I can see in the documentation, that would allow me to rejigger this. I could edit the source code, but that’s an awful lot of effort compared to building a clean implementation of only those parts of the API that I’d need.

What I do find in the documentation for Pageant are comments such as these:

  • Windows unfortunately provides no way to protect pieces of memory from being written to the system swap file. So if Pageant is holding your private keys for a long period of time, it’s possible that decrypted private key data may be written to the system swap file, and an attacker who gained access to your hard disk later on might be able to recover that data. (However, if you stored an unencrypted key in a disk file they would certainly be able to recover it.)
  • Although, like most modern operating systems, Windows prevents programs from accidentally accessing one another’s memory space, it does allow programs to access one another’s memory space deliberately, for special purposes such as debugging. This means that if you allow a virus, trojan, or other malicious program on to your Windows system while Pageant is running, it could access the memory of the Pageant process, extract your decrypted authentication keys, and send them back to its master.

I’ll address the second comment first – it’s a strange way of noting that Windows, like other modern operating systems, assumes that every process run by the user has the same access as the user. Typically, this is addressed by simply minimising the amount of time that a secret is held in memory in its decrypted form, and using something like DPAPI to store the secret encrypted.

The first comment, though, indicates a lack of experience with programming for Windows, and an inability to search. Five minutes at gets you a reference to VirtualLock, which allows you to lock 4kB at a time into physical memory, aka non-paged pool. Of course, there are other options – encrypting the Pagefile using EFS also helps protect against this kind of attack, and the aforementioned trick of holding the secret decrypted in memory for as short a time as possible also reduces the risk of having it exposed.

Now I’m really stretching to assert that this single author despises Windows and that’s why he’s completely unaware of some of its obvious security features and common modes of use. But it does seem to be a trend prevalent in some of the more religious of open source developers – “Windows sucks because it can’t do X, Y and Z” – without actually learning for certain whether that’s true. Often, X and Y can be done, and Z is only necessary on other operating systems due to quirks of their design.

Back when I first started writing Windows server software, the same religious folks would tell me “don’t bother writing servers for Windows – it’s not stable enough”. True enough, Windows 3.1 wasn’t exactly blessed with great uptime. But instead of saying “you can’t build a server on Windows”, I realised that there was a coming market in Windows NT, which was supposed to be server class. So I wrote for Windows NT, I assumed it was capable of server functionality, and any time I felt like I’d hit a “Windows can’t do this”, I bugged Microsoft until they fixed it.

Had I simply walked away and gone to a different platform, I’d be in a different place – but my point is that if you believe that your target OS is incapable, you will find it to be so. If you believe it should be capable, you will find it to be so.

3 thoughts on “Can You Write Good Code for an OS you Despise?

  1. I’ve seen this type of problem quite a bit with cross-platform applications. They tend to be very ill-behaved on the non-native platform (by non-native I mean the platform it was originally designed and built on).

    I’ve even had arguments with developers over platform specific UI semantics (e.g. SHIFT+CLICK vs. CONTROL+CLICK doesn’t work the same way on all platforms).

    If you want an application to be well rounded on all platforms, it really needs to utilize all of the platform specifics and conventions. That includes background technologies like DPAPI, Carbo, Cocoa, etc.

  2. Couple of things to add – VirtualLock doesn’t guarantee the memory will never get paged, though it would rare to have it happen. If the system is under enough memory stress, and the app hasn’t done anything for a while, the whole process could be paged out. I think the comments say as much.

  3. You have a point – a better approach, if you have to hold secrets around for a long time, is to use CryptProtectMemory and CryptUnprotectMemory.

    [Edited to refer to the Memory functions, rather than the Data functions, which are designed for storage that will last past reboots]

Leave a Reply

Your email address will not be published. Required fields are marked *