• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2012 Joyent, Inc.  All rights reserved.
2
3var assert = require('assert-plus');
4var sshpk = require('sshpk');
5var util = require('util');
6
7var HASH_ALGOS = {
8  'sha1': true,
9  'sha256': true,
10  'sha512': true
11};
12
13var PK_ALGOS = {
14  'rsa': true,
15  'dsa': true,
16  'ecdsa': true
17};
18
19function HttpSignatureError(message, caller) {
20  if (Error.captureStackTrace)
21    Error.captureStackTrace(this, caller || HttpSignatureError);
22
23  this.message = message;
24  this.name = caller.name;
25}
26util.inherits(HttpSignatureError, Error);
27
28function InvalidAlgorithmError(message) {
29  HttpSignatureError.call(this, message, InvalidAlgorithmError);
30}
31util.inherits(InvalidAlgorithmError, HttpSignatureError);
32
33function validateAlgorithm(algorithm) {
34  var alg = algorithm.toLowerCase().split('-');
35
36  if (alg.length !== 2) {
37    throw (new InvalidAlgorithmError(alg[0].toUpperCase() + ' is not a ' +
38      'valid algorithm'));
39  }
40
41  if (alg[0] !== 'hmac' && !PK_ALGOS[alg[0]]) {
42    throw (new InvalidAlgorithmError(alg[0].toUpperCase() + ' type keys ' +
43      'are not supported'));
44  }
45
46  if (!HASH_ALGOS[alg[1]]) {
47    throw (new InvalidAlgorithmError(alg[1].toUpperCase() + ' is not a ' +
48      'supported hash algorithm'));
49  }
50
51  return (alg);
52}
53
54///--- API
55
56module.exports = {
57
58  HASH_ALGOS: HASH_ALGOS,
59  PK_ALGOS: PK_ALGOS,
60
61  HttpSignatureError: HttpSignatureError,
62  InvalidAlgorithmError: InvalidAlgorithmError,
63
64  validateAlgorithm: validateAlgorithm,
65
66  /**
67   * Converts an OpenSSH public key (rsa only) to a PKCS#8 PEM file.
68   *
69   * The intent of this module is to interoperate with OpenSSL only,
70   * specifically the node crypto module's `verify` method.
71   *
72   * @param {String} key an OpenSSH public key.
73   * @return {String} PEM encoded form of the RSA public key.
74   * @throws {TypeError} on bad input.
75   * @throws {Error} on invalid ssh key formatted data.
76   */
77  sshKeyToPEM: function sshKeyToPEM(key) {
78    assert.string(key, 'ssh_key');
79
80    var k = sshpk.parseKey(key, 'ssh');
81    return (k.toString('pem'));
82  },
83
84
85  /**
86   * Generates an OpenSSH fingerprint from an ssh public key.
87   *
88   * @param {String} key an OpenSSH public key.
89   * @return {String} key fingerprint.
90   * @throws {TypeError} on bad input.
91   * @throws {Error} if what you passed doesn't look like an ssh public key.
92   */
93  fingerprint: function fingerprint(key) {
94    assert.string(key, 'ssh_key');
95
96    var k = sshpk.parseKey(key, 'ssh');
97    return (k.fingerprint('md5').toString('hex'));
98  },
99
100  /**
101   * Converts a PKGCS#8 PEM file to an OpenSSH public key (rsa)
102   *
103   * The reverse of the above function.
104   */
105  pemToRsaSSHKey: function pemToRsaSSHKey(pem, comment) {
106    assert.equal('string', typeof (pem), 'typeof pem');
107
108    var k = sshpk.parseKey(pem, 'pem');
109    k.comment = comment;
110    return (k.toString('ssh'));
111  }
112};
113