You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

112 lines
2.8 KiB

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