23 April, 2012

OpenID for Node.js v0.4.2 released

The v0.4.2 release of OpenID for Node.js fixes a bug in DH response decoding and signature calculation which caused (seemingly random) failures in the shared secret computation. This again caused some valid authentications to be rejected as invalid by OpenID for Node.js. Please upgrade to the latest version of OpenID for Node.js to avoid potentially rejecting valid authentications for your users.

Details
The bug revealed two issues in the OpenID for Node.js library:

  • The `unbtwoc` routine which converts a received binary two's complement number was flawed
  • The computed shared secret was not converted to binary two's complement form before it was used to compute the signature


These two issues together caused some authentication attempts to be rejected.

17 April, 2012

Binding a DOM element to an observable using Knockout.js

I've been doing a bit of experimenting with Knockout.js recently. Having written quite a bit of .NET code over the years, I am very used to thinking in (and I prefer thinking in) the MVVM pattern when it comes to UIs, and so Knockout.js is nice.

And, as always, when writing code and living in the real world you sometimes need to do things that do not quite fit the pattern. In this case, I needed to draw on a canvas from my view model whenever some observables on it changed. The pragmatic thing to do when you need to draw on a canvas is to just grab the canvas by ID or whatever, but since this canvas lived in a template, identifying it through selectors quickly got messy (and hard).

Binding to it seemed like a much better idea, so I created the simple `element` Knockout.js binding. This is a one-way-to-source binding (.NET guys will be familiar with this terminology), meaning that the binding only writes to the view model from the view. In addition, the binding only does this once (when it is initialized), as the element will stay for the lifespan of the page.

So, in all its glory, here is my Knockout.js `element` binding:


Use it as you would any other binding:

<canvas width="100" height="60" data-bind="element: yourObservable"></canvas>

Simple as that. Now go use it!

20 August, 2011

How to combine Git, Windows, and non-ASCII letters

The default Git installation in Windows works really bad if you're using `cmd.exe` and have non-ASCII letters in your commit information and/or code.

Thankfully, Git is highly configurable, and the fix is rather easy:


  1. Set i18n.commitencoding to the codepage you're on in cmd.exe (I'm on windows-1252)
  2. Set i18n.logoutputencoding to the same codepage.
  3. Set the LESSCHARSET environment variable to a proper name for the code page you're on (I'm on latin1), either by adding a user environment variable in Control Panel > System and Security > System > Advanced System Settings > Advanced > Environment Variables..., or setting it your cmd.exe session (e.g. set LESSCHARSET=latin1).
Boilerplate version for your copy-paste convenience (replace encodings as necessary):

    git config --global i18n.commitencodig windows-1252
    git config --global i18n.logoutputencoding windows-1252
    set LESSCHARSET=latin1

The first setting tells Git how your commit messages, including your author information, are encoded. The second tells Git what encoding it should use when writing output from a command like git log. The third and final setting tells less, the pager that Git runs git log output through, what encoding to use.

21 June, 2011

OpenID for Node.js v0.2.0 released

I am pleased to announce the release of OpenID for Node.js v0.2.0. It deserves a blog post since the new version is a bump of the minor version number. What does this mean to the users of the library?

API changes

The API of the entire thing has changed. All callbacks exposed and used by the library are now on the form callback(error, args). This convention is familiar to Node.js developers, and gives us the advantage of simpler integration with other libraries, as well as a slight increase in the fidelity of error messages.

What has changed?



  • authenticate now expects a callback which will be called with (error, authUrl). Existing code which expects (authUrl) will not get an authUrl (but possibly an error instead), and so authentication won't work after upgrade until you change your code.
  • verifyAssertion also expects a callback of the same form, which will be called with (error, result). Again, existing code depends on receiving a (result) call, and will break.
  • loadAssociation and saveAssociation must now accept a callback on the form (error, result) as an additional parameter. Previously, these functions were synchronous, so existing implementations will have to adapt so they call the callback rather than return.

What is new?

As usual, we have fixed several bugs. The library is gaining a community, and there have been several contributions along the 0.1 release path leading up to 0.2.0. Thank you all for your participation!

Apart from the changes above, 0.2.0 also introduces a discovery cache for caching discovered information. This cache is used to avoid additional HTTP requests when verifying assertions from the OpenID providers. The default cache is an in-memory cache, but you can implement your own by overloading two functions:


  • loadDiscoveredInformation(claimedIdentifier, callback) is expected to look for and load a cached provider for the given claimedIdentifier. It is expected to call callback(error, provider) when finished, with either an error or a provider (duh).
  • saveDiscoveredInformation(provider, callback) is expected to cache the given provider. The key for this object is provider.claimedIdentifier, which loadDiscoveredInformation uses for lookup. After saving, the function is expected to call callback(error) with an error if something failed, or nothing if all went well.


I have been very reluctant to make these significant API changes, but the recent development, reported issues, and feature requests have convinced me that a unified API, and a more familiar API for Node.js developers, is the right way. Also, adapting to the new API is a pretty easy process. I hope you agree with me that the introduction of these changes is best in the long run.

10 May, 2011

Diffie-Hellman support in Node.js

Yay! My patch implementing support for Diffie-Hellman key exchange in Node.js has finally been merged into the Node.js master branch. This will simplify the OpenID for Node.js codebase a lot. It will also make the OpenID association phase run a lot faster, since the current code does Diffie-Hellman in Javascript while the Node.js crypto version does it all in native code using OpenSSL.

A brief API overview:


  • crypto.createDiffieHellman(prime_length) creates a Diffie-Hellman key exchange object and generates a prime of the given bit length. The generator used is 2.
  • crypto.createDiffieHellman(prime, encoding='binary') creates a Diffie-Hellman key exchange object using the supplied prime. The generator used is 2. Encoding can be 'binary', 'hex', or 'base64'.
  • diffieHellman.generateKeys(encoding='binary') generates private and public Diffie-Hellman key values, and returns the public key in the specified encoding. This key should be transferred to the other party. Encoding can be 'binary', 'hex', or 'base64'.
  • diffieHellman.computeSecret(other_public_key, input_encoding='binary', output_encoding=input_encoding) computes the shared secret using other_public_key as the other party's public key and returns the computed shared secret. Supplied key is interpreted using specified input_encoding, and secret is encoded using specified output_encoding. Encodings can be 'binary', 'hex', or 'base64'. If no output encoding is given, the input encoding is used as output encoding.
  • diffieHellman.getPrime(encoding='binary') returns the Diffie-Hellman prime in the specified encoding, which can be 'binary', 'hex', or 'base64'.
  • diffieHellman.getGenerator(encoding='binary') returns the Diffie-Hellman prime in the specified encoding, which can be 'binary', 'hex', or 'base64'.
  • diffieHellman.getPublicKey(encoding='binary') returns the Diffie-Hellman public key in the specified encoding, which can be 'binary', 'hex', or 'base64'.
  • diffieHellman.getPrivateKey(encoding='binary') returns the Diffie-Hellman private key in the specified encoding, which can be 'binary', 'hex', or 'base64'.
  • diffieHellman.setPublicKey(public_key, encoding='binary') sets the Diffie-Hellman public key. Key encoding can be 'binary', 'hex', or 'base64'.
  • diffieHellman.setPrivateKey(public_key, encoding='binary') sets the Diffie-Hellman private key. Key encoding can be 'binary', 'hex', or 'base64'.


NOTE: The API is still subject to change.

I would appreciate getting a note if you actually do something useful with it. :) Play around with it and let me know what you think!

09 January, 2011

OpenID for node.js

I am happy to announce the immediate availability of OpenID for Node.js. I've spent a few nights working on this, which is my first Node.js library, and I finally got to the point where the library was complete enough for a first public release.

Installation

Installing is very simple using npm, just do npm install openid.

If you don't use npm, you can of course just download and require(). Remember dependencies from the lib folder, and remember adding paths to require.paths if necessary.

Usage

One of the main design goals for the library is simplicity. Using OpenID for Node.js is pretty simple, here's a minimal sample:

Source

I use GitHub for source control, so you can follow me and the node-openid repository there.

Licensing

OpenID for Node.js is licensed under the MIT license. Details can be found in the LICENSE file on GitHub. The library includes third-party code released under the MIT and BSD licenses, see README for details.

Wishes for node.js

I've come across a couple of missing features which I'd love to see in node.js in the near future:


  • The crypto module should support Diffie-Hellman key exchange (OpenSSL supports it, so please provide bindings)
  • A big integer library should be available alongside the crypto module, and preferably seamlessly integrated with the crypto module - perhaps bindings to the GMP library could suffice?
  • More seamless unit testing libraries would be good

In addition, I would love to see a tailored IDE for Node.js applications.

11 August, 2010

Mocking HtmlHelper in ASP.NET MVC 2 and 3 using Moq

Still having trouble mocking HtmlHelper? This is an update to my previous post on mocking HtmlHelper way back when ASP.NET MVC RC1 was released. Eric notified me through a comment on the post and a question on StackOverflow that the code for ASP.NET MVC RC1 did not work with ASP.NET MVC 2. The code in this post should work with ASP.NET MVC 2 and ASP.NET MVC 3 Preview 1.