test-protocol-keyparser.js 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. 'use strict';
  2. const assert = require('assert');
  3. const { readdirSync, readFileSync } = require('fs');
  4. const { inspect } = require('util');
  5. const { parseKey } = require('../lib/protocol/keyParser.js');
  6. const { EDDSA_SUPPORTED } = require('../lib/protocol/constants.js');
  7. const BASE_PATH = `${__dirname}/fixtures/keyParser`;
  8. function failMsg(name, message, exit) {
  9. const msg = `[${name}] ${message}`;
  10. if (!exit)
  11. return msg;
  12. console.error(msg);
  13. process.exit(1);
  14. }
  15. readdirSync(BASE_PATH).forEach((name) => {
  16. if (/\.result$/i.test(name))
  17. return;
  18. if (/ed25519/i.test(name) && !EDDSA_SUPPORTED)
  19. return;
  20. const isPublic = /\.pub$/i.test(name);
  21. const isEncrypted = /_enc/i.test(name);
  22. const isPPK = /^ppk_/i.test(name);
  23. const key = readFileSync(`${BASE_PATH}/${name}`);
  24. let res;
  25. if (isEncrypted)
  26. res = parseKey(key, (isPPK ? 'node.js' : 'password'));
  27. else
  28. res = parseKey(key);
  29. let expected = JSON.parse(
  30. readFileSync(`${BASE_PATH}/${name}.result`, 'utf8')
  31. );
  32. if (typeof expected === 'string') {
  33. if (!(res instanceof Error))
  34. failMsg(name, `Expected error: ${expected}`, true);
  35. assert.strictEqual(
  36. expected,
  37. res.message,
  38. failMsg(name,
  39. 'Error message mismatch.\n'
  40. + `Expected: ${inspect(expected)}\n`
  41. + `Received: ${inspect(res.message)}`)
  42. );
  43. } else if (res instanceof Error) {
  44. failMsg(name, `Unexpected error: ${res.stack}`, true);
  45. } else {
  46. if (Array.isArray(expected) && !Array.isArray(res))
  47. failMsg(name, 'Expected array but did not receive one', true);
  48. if (!Array.isArray(expected) && Array.isArray(res))
  49. failMsg(name, 'Received array but did not expect one', true);
  50. if (!Array.isArray(res)) {
  51. res = [res];
  52. expected = [expected];
  53. } else if (res.length !== expected.length) {
  54. failMsg(name,
  55. `Expected ${expected.length} keys, but received ${res.length}`,
  56. true);
  57. }
  58. res.forEach((curKey, i) => {
  59. const details = {
  60. type: curKey.type,
  61. comment: curKey.comment,
  62. public: curKey.getPublicPEM(),
  63. publicSSH: curKey.getPublicSSH()
  64. && curKey.getPublicSSH().toString('base64'),
  65. private: curKey.getPrivatePEM()
  66. };
  67. assert.deepStrictEqual(
  68. details,
  69. expected[i],
  70. failMsg(name,
  71. 'Parser output mismatch.\n'
  72. + `Expected: ${inspect(expected[i])}\n\n`
  73. + `Received: ${inspect(details)}`)
  74. );
  75. });
  76. }
  77. if (isEncrypted && !isPublic) {
  78. // Make sure parsing encrypted keys without a passhprase or incorrect
  79. // passphrase results in an appropriate error
  80. const err = parseKey(key);
  81. if (!(err instanceof Error))
  82. failMsg(name, 'Expected error during parse without passphrase', true);
  83. if (!/no passphrase/i.test(err.message)) {
  84. failMsg(name,
  85. `Error during parse without passphrase: ${err.message}`,
  86. true);
  87. }
  88. }
  89. if (!isPublic) {
  90. // Try signing and verifying to make sure the private/public key PEMs are
  91. // correct
  92. const data = Buffer.from('hello world');
  93. res.forEach((curKey) => {
  94. let result = curKey.sign(data);
  95. if (result instanceof Error) {
  96. failMsg(name,
  97. `Error while signing data with key: ${result.message}`,
  98. true);
  99. }
  100. result = curKey.verify(data, result);
  101. if (result instanceof Error) {
  102. failMsg(name,
  103. `Error while verifying signed data with key: ${result.message}`,
  104. true);
  105. }
  106. if (!result)
  107. failMsg(name, 'Failed to verify signed data with key', true);
  108. });
  109. if (res.length === 1 && !isPPK) {
  110. const pubFile = readFileSync(`${BASE_PATH}/${name}.pub`);
  111. const pubParsed = parseKey(pubFile);
  112. if (!(pubParsed instanceof Error)) {
  113. let result = res[0].sign(data);
  114. if (result instanceof Error) {
  115. failMsg(name,
  116. `Error while signing data with key: ${result.message}`,
  117. true);
  118. }
  119. result = pubParsed.verify(data, result);
  120. if (result instanceof Error) {
  121. failMsg(name,
  122. 'Error while verifying signed data with separate public key: '
  123. + result.message,
  124. true);
  125. }
  126. if (!result) {
  127. failMsg(name,
  128. 'Failed to verify signed data with separate public key',
  129. true);
  130. }
  131. }
  132. }
  133. }
  134. });