/**
 * Module dependencies.
 */
var uri = require('url')
  , request = require('request')
  , Factory = require('./factory')
  , RSAKey = require('./keys/rsa')
  , debug = require('debug')('nks-jwks');


/**
 * Finds a key in a JSON Web Key Set.
 *
 * References:
 *  - [JSON Web Key (JWK)](http://tools.ietf.org/html/draft-ietf-jose-json-web-key-20)
 *
 * @param {Object} options
 * @return {Function}
 * @api public
 */
module.exports = function(options) {
  options = options || {};
  var use = options.use || 'sig';
  if (use == 'signature') { use = 'sig'; }
  if (use == 'encryption') { use = 'enc'; }

  var factory = new Factory();
  factory.use(RSAKey);
  
  return function jwks(entity, options, cb) {
    // TODO: support entity as string or object
    
    var url = entity.jwksUrl;
    
    // This entity does not have a JWK Set.  Invoke callback without an error or
    // key.  If additional mechanisms are supported, attempts to find the key
    // will continue.
    if (!url) { return cb(); }
    
    request({
      url: url,
      headers: {
        'Accept': 'application/json'
      }
    }, function(err, res, body) {
      if (err) { return cb(err); }
      if (res.statusCode != 200) {
        return cb(new Error('Unexpected status ' + res.statusCode + ' from ' + url));
      }
      
      var json;
      try {
        json = JSON.parse(body);
      } catch (ex) {
        return cb(new Error('Failed to parse JWK Set from ' + url));
      }
      
      var jwks = json.keys || []
        , jwk, i, len
        , keys = [], key, skey;
      for (i = 0, len = jwks.length; i < len; i++) {
        jwk = jwks[i];
        
        if (jwk.use && jwk.use != use) { continue; }
        if (jwk.alg && jwk.alg != options.alg) { continue; }
        
        key = factory.create(jwk);
        if (!key) { continue; }
        if (key.supports(options.alg)) {
          keys.push(key);
        }
      }
      
      
      skey = keys[0];
      for (i = 0, len = keys.length; i < len; i++) {
        key = keys[i];
        if (key.id && key.id == options.kid) {
          skey = key;
          break;
        }
      }
      
      if (!skey) {
        // TODO: Better error message
        return cb(new Error('No suitable key'));
      }
      
      
      return cb(null, skey.toPEM());
    });
    
  }
};

@@ -249,105 +249,863 @@
 %0A * 
-References:%0A *  - %5BJSON Web Key (JWK)%5D(http://tools.ietf.org/html/draft-ietf-jose-json-web-key-20
+This finder finds keys or certificates in a JSON Web Key Set (JWK Set).  By%0A * default, it selects keys used for signing and supports finding a specific key%0A * by ID, which is useful during key rollover.%0A *%0A * In order for this finder to operate, the entity musth have a %60jwksUrl%60%0A * property.  It is assumed that the value of this property has been verified as%0A * belonging to the entity in question.  How this is accomplished is out of%0A * scope of this package, but it is an important security consideration for the%0A * application to ensure.  See the %22Related Packages%22 section below for packages%0A * that can assist in this process.%0A *%0A * References:%0A *  - %5BJSON Web Key (JWK)%5D(http://tools.ietf.org/html/draft-ietf-jose-json-web-key-20)%0A *%0A * Related Packages:%0A *  - %5Bnds-openidconfiguration%5D(https://github.com/jaredhanson/node-nds-openidconfiguration
 )%0A *
@@ -1357,16 +1357,47 @@
 'enc'; %7D
+%0A  var secure = options.secure;
 %0A%0A  var 
@@ -1497,61 +1497,8 @@
 ) %7B%0A
-    // TODO: support entity as string or object%0A    %0A
     
@@ -1741,24 +1741,165 @@
 b(); %7D%0A    %0A
+    var purl = uri.parse(url);%0A    if (!(purl.protocol == 'https:' %7C%7C (purl.protocol == 'http:' && secure === false))) %7B return cb(); %7D%0A    %0A
     request(
@@ -3143,24 +3143,86 @@
     %0A      %0A
+      // TODO: Implement support for fetching x5u URLs%0A      %0A
       return

Add documentation.