| // Copyright 2012 Joyent, Inc. All rights reserved. |
| |
| var assert = require('assert-plus'); |
| var sshpk = require('sshpk'); |
| var util = require('util'); |
| |
| var HASH_ALGOS = { |
| 'sha1': true, |
| 'sha256': true, |
| 'sha512': true |
| }; |
| |
| var PK_ALGOS = { |
| 'rsa': true, |
| 'dsa': true, |
| 'ecdsa': true |
| }; |
| |
| function HttpSignatureError(message, caller) { |
| if (Error.captureStackTrace) |
| Error.captureStackTrace(this, caller || HttpSignatureError); |
| |
| this.message = message; |
| this.name = caller.name; |
| } |
| util.inherits(HttpSignatureError, Error); |
| |
| function InvalidAlgorithmError(message) { |
| HttpSignatureError.call(this, message, InvalidAlgorithmError); |
| } |
| util.inherits(InvalidAlgorithmError, HttpSignatureError); |
| |
| function validateAlgorithm(algorithm) { |
| var alg = algorithm.toLowerCase().split('-'); |
| |
| if (alg.length !== 2) { |
| throw (new InvalidAlgorithmError(alg[0].toUpperCase() + ' is not a ' + |
| 'valid algorithm')); |
| } |
| |
| if (alg[0] !== 'hmac' && !PK_ALGOS[alg[0]]) { |
| throw (new InvalidAlgorithmError(alg[0].toUpperCase() + ' type keys ' + |
| 'are not supported')); |
| } |
| |
| if (!HASH_ALGOS[alg[1]]) { |
| throw (new InvalidAlgorithmError(alg[1].toUpperCase() + ' is not a ' + |
| 'supported hash algorithm')); |
| } |
| |
| return (alg); |
| } |
| |
| ///--- API |
| |
| module.exports = { |
| |
| HASH_ALGOS: HASH_ALGOS, |
| PK_ALGOS: PK_ALGOS, |
| |
| HttpSignatureError: HttpSignatureError, |
| InvalidAlgorithmError: InvalidAlgorithmError, |
| |
| validateAlgorithm: validateAlgorithm, |
| |
| /** |
| * Converts an OpenSSH public key (rsa only) to a PKCS#8 PEM file. |
| * |
| * The intent of this module is to interoperate with OpenSSL only, |
| * specifically the node crypto module's `verify` method. |
| * |
| * @param {String} key an OpenSSH public key. |
| * @return {String} PEM encoded form of the RSA public key. |
| * @throws {TypeError} on bad input. |
| * @throws {Error} on invalid ssh key formatted data. |
| */ |
| sshKeyToPEM: function sshKeyToPEM(key) { |
| assert.string(key, 'ssh_key'); |
| |
| var k = sshpk.parseKey(key, 'ssh'); |
| return (k.toString('pem')); |
| }, |
| |
| |
| /** |
| * Generates an OpenSSH fingerprint from an ssh public key. |
| * |
| * @param {String} key an OpenSSH public key. |
| * @return {String} key fingerprint. |
| * @throws {TypeError} on bad input. |
| * @throws {Error} if what you passed doesn't look like an ssh public key. |
| */ |
| fingerprint: function fingerprint(key) { |
| assert.string(key, 'ssh_key'); |
| |
| var k = sshpk.parseKey(key, 'ssh'); |
| return (k.fingerprint('md5').toString('hex')); |
| }, |
| |
| /** |
| * Converts a PKGCS#8 PEM file to an OpenSSH public key (rsa) |
| * |
| * The reverse of the above function. |
| */ |
| pemToRsaSSHKey: function pemToRsaSSHKey(pem, comment) { |
| assert.equal('string', typeof (pem), 'typeof pem'); |
| |
| var k = sshpk.parseKey(pem, 'pem'); |
| k.comment = comment; |
| return (k.toString('ssh')); |
| } |
| }; |