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