Monday, September 9, 2013

electronic communication for the a-social

I'm not anti-social. I can't be; I have a Klout score that hovers around 50. But lately I've realized I'm ready to leave Twitter and Facebook behind.

I started on computers young. My mom and dad were in the position to put me in front of some of the more innovative, connected computing systems of the early 80's. Dad was a pretty senior tech person in the Air Force and my mom was in education research. And we hit the beginning of the micro-computer revolution perfectly. We were one of those early adopters families; we had a passable home computer and a modem in the summer of '78. Within a year, I discovered I had a second cousin who worked at AT&T and was able to get me an account on an early unix machine (and later, on ATTCTC.) I believe I was the only kid in my 7th grade class writing C programs on Unix.

I feasted on the libertarian culture of the usenet and early BBSes. I remember the day I got my first "real" email account and the joy of having to work out how many bangs people needed to put in it for mail to actually reach me. But here's the thing, the libertarian-democratic ideal of the early internet requires people to behave responsibly, not like entitled ass-hats.

Like everyone else on the early internet, I thought of myself as an advanced individual developing tools to make people's lives better. We were developing technology to cheaply communicate across national borders, enable physically disabled people and making geographic distance irrelevant. The 'net was going to change society for the better. We had a few news groups dedicated to porn, but the vast majority seemed to be about bringing people into the electronic forum and letting them find kindred souls to refine their ideas.

I was on the 'net in September 1993 when the AOL hoard overran the Usenet. Several months in, I was pretty amazed to discover that AOL peeps were, for the most part, not the classless hoard we thought they would be. Things looked good.

But then it started being about money, not people.

Don't get me wrong. I'm not a communist. I have a love-hate relationship with Capitalism, but I'm enough of a bleeding liberal to think we should add some reasonable regulation to the markets. But what happened in the run-up to the dot bomb was pretty sad to see.

Financial markets caught wind of what was going on in Sili Valley and every trader with an AOL account realized where the future was headed. Every business school grad who could spell CPU put together a plan to sell hardware, software or information. Most plans were complete garbage, but what did it matter? Once you get initial funding, you keep going until you can sell a chunk of your company to some other, bigger fool.

Where once we built (mostly) working systems to fit the needs of our users, we were now asked to build incomplete systems that looked plausible. Utility was less important than subscriber growth, because the business people wrote some very nice documents describing how, at any moment, they could convert subscriber growth into income. But why do that now when we still have a little money in the bank; we can optimize our profits by growing as big as we can as fast as we can before we start monetizing.

Everyone knows how this story ends: broken dreams, broken products and more than a few broken marriages. Those who survived licked their wounds and got back to building things. This time around we built things we could sell and we much more cautious about pushing lies about converting eyeballs to money.

But one thing that didn't ever come back... the idea that the user is in control. Sure, the user is the "center" of modern digital systems. But that's because Facebook, Twitter and Google are selling your eyeballs to advertisers. And that's okay as long as we're all honest about what's going on. But slowly we started to see federated identity systems manged by big sites leak information about users to advertisers. And don't get me started about the NSA thing.

So this is what we've become: a network of eyeballs to be sold to purveyors of crap. In the words of Tim Rice's KGB Agent from Chess, we're "prostituting ourselves, chasing a spurious star-light -- trinkets on [web pages] sufficient to lead us astray."

I'm not saying Facebook, Twitter and various Google services aren't without utility. They are quite useful at times. But we're paying too high a price for ubiquity of audience and benign voyeuristic pleasures. I love being able to talk to my relatives on Facebook, but do I really need to see so many animated GIFs of twerking celebrities?

And don't get me started about the tech culture that produced the titstare spectacle. In 1978, Aleksandr Solzhenitsyn observed that the United States was "spiritually weak and mired in vulgar materialism." In 2013, I observe that Solzhenitsyn was an optimist.

So what to do about it?

It's interesting to note that Donald Knuth (whom many consider to be the "father" of algorithm analysis) hasn't had an email account since 1990. One wonders how he is able to renew his driver's license or open a bank account. I envy Dr. Knuth's ability to function without a persistent email mailbox, but I'm not sure I could survive completely without one.

To be sure, I think we could all spend a little less time grooming our inboxes; the zero inbox concept seems patently absurd to me. It simply means you subscribe to no mailing lists and haven't given your email address to marketers.

I think the first thing we may want to consider is limiting how "available" you are. It's the third millennium; an email address is not a novel concept. You derive no social capital simply by being online. You don't have to paste your email address on every web page you produce. Consider using a web-form with a comment box (or heck, put your email address on a gopher server somewhere.) Make it easy for a human to reach you, but hard to communicate your email address to marketers and i suspect you'll have a better email experience.

Consider ignoring email through the day. Look at it once in the evening and/or once in the afternoon. Where I work we use an IRC room to communicate for important things and email to communicate status and not-overly-time-sensitive topics. If you want to kill your productivity, marry yourself to your email account.

Second, go without Facebook or Twitter for a day. I do this from time to time. I've never been a "big" Facebook person to begin with. But try stepping away once in a while. It will be there when you get back.

And lastly, consider starting or joining a "dark" social network. I've been working on these things for a bit. A "dark" social network is one with a fixed membership that is completely undetectable by the public internet. You use a browser to access it, but it doesn't have a welcome and registration screen as much as it has a "NOT FOUND" screen for anyone who doesn't know the right URL.

This isn't so much a security feature as it is an obscurity feature. It's bad to have security by obscurity, but if you actually use "real" security features like strong passwords and TLS along with obscurity, you gain the ability to not have to tell the guy you don't like your account name on this hidden service.

Dark social networks are dark only to the degree everyone in the network keeps the network's existence private. And I think we all know how well our friends keep secrets. So be careful out there; just 'cause something's dark doesn't mean it will stay that way.

One bit of "dark fun" I've been having lately is using obsolete protocols. When was the last time you were on Usenet? or used a Gopher server? Heck, most modern browsers don't even support them anymore.

Now I have to run along and update the contents on my gopher server. Cheers, all!

Saturday, August 10, 2013

Generating Self-Signed X.509 Certificates

People who know me know that I love to dis on X.509 based security solutions. Whether it's implementations that just plain ignore basic constraints, or popular certification authorities that add an extra zero byte to the end of their certs... it's all just so much fun.

But it's hard to argue with the utility of a properly configured TLS layer. And until we add a TLS extension for using OpenPGP to cart around public keys in TLS handshake sequences, we're sort of stuck with X.509.

I spend a surprising amount of time generating self-signed certificates for testing, so a few decades ago I came up with a bash script to eliminate the drudgery of this process. If you're interested, just grab a copy from GitHub.

To use it, just copy and paste it from the gist page into a file you've chmod +x'd. To use it, just run the script passing the name of the host you're generating a certificate for as the first parameter. It defaults to making 2048 bit keys with no passwords, so don't use this to generate production certs (not that you should be using self-signed certificates in a production environment anyway.)

So if I wanted to create a certificate for www.example.com, and I named the script gssc, i would invoke it like so:
gssc www.example.com
and it would generate two files: www.example.com.key and www.example.com.crt. The former contains the private key and the latter is the X.509 certificate for www.example.com.

The -b, -p and -s options allow you to change the length of the private key, the password to encrypt the private key and the certificate's subject name. So if I wanted to create a 1024 bit private key, encrypted with the password "blargh" and with the subject name "C=IO, ST=Chacos, L=Diego Garcia, CN=www.example.mil," I would use this command:
gssc www.example.mil -b 1024 -p blargh \
  -s "/C=IO/ST=Chacos/L=Diego Garcia/CN=www.example.mil"
Cheers!

Monday, August 5, 2013

In Defense of JavaScript Cryptography

Google "javascript cryptography" and you'll quickly find a fair number of people dismissing JS Crypto as a fools errand. My favorite is the Matasanto Security article entitled "JavaScript Cryptography Considered Harmful." The tone of the article seems a little alarmist to me. But... it also happens to bring up a few really great points. Its critique of the current state of web app crypto is mostly spot-on. However,  the state of the art is evolving quickly and may soon make the Matasano Security article mostly irrelevant.

This post is a brief rebuttal to the assertion that JavaScript cryptography should be considered "harmful." I would completely agree with "fraught with serious challenges" and "difficult to do right," but certainly not harmful.

Why Do JavaScript Crypto?

Before you can make a blanket statement like "JS Crypto is EVIL," you really should list out a few use cases. I think it's fair to say replicating HTTPS functionality in JavaScript is a poor idea. All popular browsers provide built-in support for HTTPS. What's more, these implementations have all been reviewed by multiple people to help ensure correctness and freedom from obvious bugs. So if you're just trying to communicate a password from a browser to a web server, use HTTPS. Don't try to replicate that functionality by yourself with JavaScript.

But there are several use cases where JS Crypto may be advantageous. The two I can think of off the top of my head are end-to-end message security and Secure/Stanford Remote Password (SRP) support. Neither of these use cases are directly supported by modern browsers and are of interest to the general community.

End-to-End message security means encrypting a message in such a way that it can only be decrypted by its intended recipient. In the context of JavaScript crypto, this means your favorite email, microblogging or IM web app uses JavaScript to encrypt your message. The encrypted message is then sent to its destination by whatever means and is ultimately decrypted by a web app running on the recipient's machine. In the end-to-end encryption scenario, the server never has access to your decrypted message; and unless you explicitly share your keys with the server, they never will.

End-to-end message security contrasts with "Transport Security" offered by SSL/TLS. HTTPS, which uses Secure Sockets Layer (SSL) aka Transport Layer Security (TLS), encrypts the link between the browser and the web server. To communicate securely with another person, you would send an un-encrypted message to your web server over the encrypted HTTPS link. The server would then forward the message to its recipient using a different (hopefully) encrypted HTTPS link. Because the message is un-encrypted when it gets to the server, the server operator can see the contents of the message. But because the link is encrypted, eavesdroppers listening in to the conversation should not be able to read the message.

Secure Remote Password (SRP), formerly known as Stanford Remote Password, is an authentication protocol with many desirable features: it is resistant to password dictionary attacks and establishes a shared session key which may be used to authenticate or encrypt messages between a client and server. Or, more likely, between a client and a piece of computing equipment "behind" the web server for which the web server acts as a proxy. To be sure, the SRP's utility is diminished by the near universal support of SSL/TLS, but there are definitely situations where it can be useful.

These are not the only reasons why you might want to use something other than HTTPS; but they are two reasonably important use cases not directly supported by SSL/TLS.

The Chicken and the Egg

The Matasano article assumes the reason you're using JavaScript crypto in your browser is to encrypt a user password for its trip from the browser to the server. It then presents this "chicken and egg" problem:
  • if you don't trust the internet to securely deliver a password from the browser to the client, why trust it to deliver a JavaScript encryption library?
  • and if you use HTTPS to ensure no one's tampered with your JavaScript encryption library, why not just use HTTPS to secure your password and be done with it.
I mostly agree with this assessment. However, there may be a situation where your javascript encryption library is served off a different host than the one you're communicating with. Imagine you're trying to communicate with an 8 or 16 bit microcontroller. There are several on the market today with enough CPU horsepower, memory and IO to speak SLIP or PPP (or even IPv6.) Due to policy, debugging or legal reasons, you may serve TLS pages off the microcontroller using only authentication. It's a bit of a corner-case, but I've actually found myself in exactly that situation. My microcontroller could handle authentication with ECDSA, but couldn't cope with a bulk cipher I was willing to use.

But there are some interesting developments in the chicken and egg question. It turns out there's a group of people working on a specification to introduce cryptographic primitives to the JavaScript in browsers. The Web Cryptography API is an emerging standard from the W3C and will provide basic crypto functions to JS web apps. When widely deployed, this should eliminate most the concerns dealing with the question "hey! where did my crypto implementation come from?"

Good Random Numbers

The Matasano article correctly observes the JavaScript Math.random() function is inappropriate for use in "real" security protocols. It simply doesn't utilize sufficient entropy. Fortunately, Chrome and Firefox have implemented the random number generator from the Web Cryptography API in recent builds. According to this Mozilla Development Network page, support for crypto.getRandomValues() was added in Chrome 11 and Firefox 21.

If you are truly interested in properly implementing security-related protocols, you must use this call instead of Math.random().

Extensible Languages and Insecure Content

IMHO, the fundamental concern with web apps is the risk that occurs when JavaScript's extensible nature meets insecure content. The Matasano article talked about this in the context of downloading javascript to implement crypto primitives, but once a bad guy can inject code into your JS execution context, it's all borked, not just the crypto.

The problem here stems from the fact that JavaScript is, by design, an extensible programming language. It's possible to replace some of the basic functions provided by JavaScript and the DOM API. Here's a simple example where I replace the escape() function with a function that reverses a string before escaping it:

window.prevescape = window.escape;
window.escape = function( input ) {
  var output = "";
  for( var i = 1, il = input.length; i <= il; i ++ ) {
    output += input.substr( input.length - i, 1 );
  }
  return prevescape( output );
};

This example doesn't do anything horrible, but it should demonstrate how easy it is to extend or even replace core JavaScript functionality. And it's just as easy to replace the code that manages import / export of cryptographic keys as it is to replace the escape() function.

The ability to replace or extend JavaScript functionality is a good thing when you're using it to fix bugs or add useful features. But if a bad guy can insert a script tag into your page, all bets are off, you're completely 0wn3d. Since it's unlikely you're going to hack your own web app, we need to figure out a way to prevent black hat script tags from appearing in your web page.

In Conclusion

Securely executing JavaScript applications in a browser is not hopelessly borked. Neither is JavaScript Crypto. You have to take care to defend against common vulnerabilities introduced by user generated content. Unless you defend against a man in the middle by sending content capable of modifying the javascript execution context over TLS, it will possible for a bad guy to insert bad guy code into your web application.

Progress is being made with the introduction of the Content Security Policy and Web Cryptography API specifications from the W3C. We're even starting to see browser developers implement them, which is a good thing.

But more work needs to be done to "secure" javascript code. It could be as simple as making the browser's crypto object read only. This would not eliminate all vulnerabilities, but will reduce the attack cross section. We could also require that all scripts referencing the crypto object adhere to common same-origin protections (modulo CORS or CSP.)

This article reflects my personal opinion, and may not reflect opinions or policies of my employer.

Thursday, August 1, 2013

A Couple Useful Aliases for EMACS

Yes. I am an Emacs user. (or, as i call it... EMACS... the editor so ossm, you have to write it in all caps!) But there are a few things I don't like about Emacs, and here's the simple solution I found for them.

Problem 1 : Trailing White-Space is Of the Devil

So if you look at the Mozilla bugs I tried to fix, I think they all have a comment from bsmith and ekr saying something like "uh.. trailing white-space." Yes. It is the sad truth, but God's own text editor has issues with leaving trailing white-spaces in code. I don't remember it used to have this problem in the 80's, so obviously this is Apple's fault.

Seriously though... I could have sworn this didn't used to be a problem. Maybe it's just we had worse tools for detecting trailing white-space and I just didn't notice. But it's really noticeable when you try to generate diffs to attach to bug reports. (The Mozilla process is to attach a diff to a bug, get it reviewed and then apply it to a repository somewhere.)

At first, I simply tried to just delete all trailing white-space in the file I was working on, but any given file in the Firefox source base, one in a hundred lines has trailing white-space so I wound up making diffs with bajillions of updates that had nothing to do with the issue at hand. To me, this stinks of bad form.

Yes, I should have created a bug titled "file foo.cpp has a lot of trailing white-space" and applied the change there, but there was about zero chance of the bug getting a positive review without someone saying "hey! why don't we refactor all the code and add these other features while we're removing all this trailing white-space." And honestly, I got tired of saying "don't make me slap you..." to all the people who suggested this.

So rather than debug a bunch of elisp code, I figured I would take inspiration from the hackers of old and just use a sed script to fix the problem. It removes trailing white-space from lines that begin with a plus ('+') character. If you're familiar with diff or patch tools you'll understand why I did this. Here's the alias I added in my .bashrc file:
alias bongo='sed -e '"'"'s/^\+\(.*[^ \t]\)[ \t]*$/\+\1/'"'"''
You can now do things like this if you don't trust your ability to spot trailing white-space in your code:
hg diff | bongo > current.diff
or if you don't trust other people, you can do this:
cat random.diff | bongo | patch -p1
Problem 2 : I Usually Don't Like EMACS in XWindows

But sometimes I do. So I do the following:
alias emacs='emacs -nw'
This tells emacs to launch in the current terminal window.

Hope these suggestions help, or inspire you to hack your own environment. -Cheers!

Wednesday, June 26, 2013

just sayin'

so i come from a family chock-full of baptist missionaries. my brain's been kind of stretched over the last couple days trying to square my love for my extended family with my own urge to stand up and call bullshit on this whole southern christian homophobia thing.

so let me just say this to my southern christian friends: i love you deeply and always will. i have no frame of reference to understand your opposition to same-sex marriage, but will accept it since to do anything else would be to deny your personal agency.

but i do disagree with you, and likely i always will. i hope that in time you will see same-sex marriage does nothing to diminish your marriage. i hope you recognize the desire to live in monogamous marriages extends to all sorts of people: gay, straight and all things in-between. i hope you will see that the gender of a child's parents has infinitely less to do with that child's welfare than the love and support offered the child from the parents.

my take on christ's message is we must all seek salvation by challenging ourselves to love those whom we once hated. the "conversion experience" is a chance to open our hearts and see the reflection of the divine spark hidden in the souls of others.

i love you not because the bible tells me to love you, but because it brings me closer to  my god. i do not agree with you, but i love you and no matter what you think about me or my marriage, i always will.

Monday, June 24, 2013

Learn how to encrypt your email with FREE tools (in Santa Cruz)

I was planning on meeting a few people for coffee on Thursday night (27 June, 2013) at Caffe Pergolesi in Santa Cruz and show them how to set up PGP/GPG + EnigMail so they can do encrypted email. Then a few more people started asking if they could come by...

So... if you live in Santa Cruz and want me to help you setup PGP/GPG Encrypted email (so the feds / advertisers / spouse can't read your email) come on by. If it's not raining, I'll probably be sitting outside speaking loudly about encryption technology.

So... 7:30 'til about 9ish at the perg this coming Thursday. Bring your laptop.

And if you already have a PGP key, come on by and we can do the key signing thing.

Sunday, June 2, 2013

Installing VMS on Your Raspberry Pi

What is more pure than young love? And my first love in high school was for VMS, Digital Equipment Corporation's operating system from the late 70's. Sure, Unix (tm) and it's derivatives are the work-horses of modern computing, but VMS was the first "real" operating system I used. Using VMS in the modern era makes me a bit of an anachronism, but there were plenty of features I still kind of miss from the old days:

  1. A sane default editor. Sure, I love emacs and vi, but you have to admit, their obscure key-commands create a bit of a learning curve. VMS's default edit command used arrow keys to move around and saved changes by default. (okay, this is more of a nit than a real feature, but still...)
  2. Versioned files. VMS's file system, FILES-11, allowed you to save multiple revisions of the same file. When you created a file with an existing name, the default behavior was to create a new revision. If you made a total hash of things, reverting was as simple as deleting the most recent version.
  3. Pervasive Help Files. Help files were managed centrally and IMHO thought out a little better than the Unix man page system. Also, the command to get help was help, which is more intuitive than "man."
  4. Logical directories spanning devices. While not as "pure" as "union directories," it was possible to set the current working directory to a list instead of a single location in the filesystem. This had the effect of letting many commands search for files in multiple directories.
But the most important reason for using VMS these days is it's fun to challenge your status quo and try new things. And besides, I had a lot of fun with some of those old MicroVAXes, so this brings me back to a fun time in my life.

Setting up a VMS system is relatively easy (even for a novice.) The good people at trailing-edge.com distribute an open source VAX Emulator (and btw, the simh emulator emulates many other old systems.) Hewlett-Packard, the current owners of VMS, offer downloadable VMS install media free of charge for non-commercial hobbyists. And Phil Wherry has put together a really top-knotch guide for installing VMS on the simh emulator.

So if you want to join me in VMS-style retrocomputing, it should be as easy as downloading and installing the emulator, requesting a hobbyist license from HP and following Phil's install instructions.

A few things have changed since Phil wrote his install guide, so here are a few notes you may want to read to avoid frustration:
  1. Don't use a wireless network as your primary network interface. Unless you use the TUN/TAP bridge described in the 0readme_ethernet.txt file in the simh source distribution, you may encounter issues placing your wireless network device into promiscuous mode.
  2. HP no longer requires you to buy physical install media; you can download the files you need to install VMS directly from the web. You still need to enroll as a hobbyist with HP, but the process is a little easier and takes considerably less time than it used to. HP requires you to be a member of a properly sanctioned users group before handing out licenses, but if you've forgotten your DECUS subscriber information (like I have) you can apply for a free online account with DECUSERVE.ORG. Once you're signed up with them, head over to openvms.org for more info on how to create the account.
  3. After you register, you'll get a license file from HP. Search for the VAX-VMS entry; it should look like this:
    $! This PAK issued on DD-MMM-YYYY HH:MM
    $ Call CheckLicense "VAX-VMS" "DD-MMM-YYY"
    $ IF ($STATUS .EQS. "%X107880D3") .OR. ($STATUS .EQS. "%X107880CB")
    $ THEN
    $!
    $ LICENSE REGISTER VAX-VMS - 
    /ISSUER=DEC - 
    /AUTHORIZATION=HOBBYIST-VA-KEYxxxxx-xxxxxx - 
    /PRODUCER=DEC - 
    /UNITS=0 - 
    /TERMINATION_DATE=DD-MMM-YYYY - 
    /ACTIVITY=CONSTANT=100 - 
    /CHECKSUM=y-yyyy-yyyy-yyyy-yyyy
    $!
    $ LICENSE DISABLE VAX-VMS/LOG/PRODUCER=DEC/ALL
    $ LICENSE UNLOAD  VAX-VMS/LOG/PRODUCER=DEC
    $ LICENSE ENABLE  VAX-VMS/LOG/PRODUCER=DEC/AUTH=HOBBYIST-VA-KEYxxxxx-xxxxxx
    $ LICENSE LOAD    VAX-VMS/LOG/PRODUCER=DEC
    $ ENDIF
    $ !

    When it's time to enter the license info during installation, enter only the fields that are listed in the license:

    Issuer [DEC]: DEC
    Authorization Number []: HOBBYIST-VA-KEYxxxxx-xxxxxx
    Product Name []: VAX-VMS
    Producer [DEC]: DEC
    Number of Units [1]: 0
    Version []:
    Product Release Date []: 
    Key Termination Date []: DD-MMM-YYYY
    Availability Table Code []: 
    Activity Table Code []: CONSTANT=100
    Key Options []: 
    Include Node []: 
    Product Token []: 
    Hardware-Id []: 
    Checksum []: y-yyyy-yyyy-yyyy-yyyy
    

At the end or the process, you should have a perfectly serviceable VMS System. Enjoy!