Newer
Older
CVSS_3.0_GUI / dist / CVSS_3.0_Calc-1.0.0-linux-x64 / node_modules / nwjs-builder-phoenix / node_modules / request / node_modules / http-signature / node_modules / sshpk / lib / formats / rfc4253.js
root on 7 May 2019 4 KB Initial commit
  1. // Copyright 2015 Joyent, Inc.
  2.  
  3. module.exports = {
  4. read: read.bind(undefined, false, undefined),
  5. readType: read.bind(undefined, false),
  6. write: write,
  7. /* semi-private api, used by sshpk-agent */
  8. readPartial: read.bind(undefined, true),
  9.  
  10. /* shared with ssh format */
  11. readInternal: read,
  12. keyTypeToAlg: keyTypeToAlg,
  13. algToKeyType: algToKeyType
  14. };
  15.  
  16. var assert = require('assert-plus');
  17. var Buffer = require('safer-buffer').Buffer;
  18. var algs = require('../algs');
  19. var utils = require('../utils');
  20. var Key = require('../key');
  21. var PrivateKey = require('../private-key');
  22. var SSHBuffer = require('../ssh-buffer');
  23.  
  24. function algToKeyType(alg) {
  25. assert.string(alg);
  26. if (alg === 'ssh-dss')
  27. return ('dsa');
  28. else if (alg === 'ssh-rsa')
  29. return ('rsa');
  30. else if (alg === 'ssh-ed25519')
  31. return ('ed25519');
  32. else if (alg === 'ssh-curve25519')
  33. return ('curve25519');
  34. else if (alg.match(/^ecdsa-sha2-/))
  35. return ('ecdsa');
  36. else
  37. throw (new Error('Unknown algorithm ' + alg));
  38. }
  39.  
  40. function keyTypeToAlg(key) {
  41. assert.object(key);
  42. if (key.type === 'dsa')
  43. return ('ssh-dss');
  44. else if (key.type === 'rsa')
  45. return ('ssh-rsa');
  46. else if (key.type === 'ed25519')
  47. return ('ssh-ed25519');
  48. else if (key.type === 'curve25519')
  49. return ('ssh-curve25519');
  50. else if (key.type === 'ecdsa')
  51. return ('ecdsa-sha2-' + key.part.curve.data.toString());
  52. else
  53. throw (new Error('Unknown key type ' + key.type));
  54. }
  55.  
  56. function read(partial, type, buf, options) {
  57. if (typeof (buf) === 'string')
  58. buf = Buffer.from(buf);
  59. assert.buffer(buf, 'buf');
  60.  
  61. var key = {};
  62.  
  63. var parts = key.parts = [];
  64. var sshbuf = new SSHBuffer({buffer: buf});
  65.  
  66. var alg = sshbuf.readString();
  67. assert.ok(!sshbuf.atEnd(), 'key must have at least one part');
  68.  
  69. key.type = algToKeyType(alg);
  70.  
  71. var partCount = algs.info[key.type].parts.length;
  72. if (type && type === 'private')
  73. partCount = algs.privInfo[key.type].parts.length;
  74.  
  75. while (!sshbuf.atEnd() && parts.length < partCount)
  76. parts.push(sshbuf.readPart());
  77. while (!partial && !sshbuf.atEnd())
  78. parts.push(sshbuf.readPart());
  79.  
  80. assert.ok(parts.length >= 1,
  81. 'key must have at least one part');
  82. assert.ok(partial || sshbuf.atEnd(),
  83. 'leftover bytes at end of key');
  84.  
  85. var Constructor = Key;
  86. var algInfo = algs.info[key.type];
  87. if (type === 'private' || algInfo.parts.length !== parts.length) {
  88. algInfo = algs.privInfo[key.type];
  89. Constructor = PrivateKey;
  90. }
  91. assert.strictEqual(algInfo.parts.length, parts.length);
  92.  
  93. if (key.type === 'ecdsa') {
  94. var res = /^ecdsa-sha2-(.+)$/.exec(alg);
  95. assert.ok(res !== null);
  96. assert.strictEqual(res[1], parts[0].data.toString());
  97. }
  98.  
  99. var normalized = true;
  100. for (var i = 0; i < algInfo.parts.length; ++i) {
  101. var p = parts[i];
  102. p.name = algInfo.parts[i];
  103. /*
  104. * OpenSSH stores ed25519 "private" keys as seed + public key
  105. * concat'd together (k followed by A). We want to keep them
  106. * separate for other formats that don't do this.
  107. */
  108. if (key.type === 'ed25519' && p.name === 'k')
  109. p.data = p.data.slice(0, 32);
  110.  
  111. if (p.name !== 'curve' && algInfo.normalize !== false) {
  112. var nd;
  113. if (key.type === 'ed25519') {
  114. nd = utils.zeroPadToLength(p.data, 32);
  115. } else {
  116. nd = utils.mpNormalize(p.data);
  117. }
  118. if (nd.toString('binary') !==
  119. p.data.toString('binary')) {
  120. p.data = nd;
  121. normalized = false;
  122. }
  123. }
  124. }
  125.  
  126. if (normalized)
  127. key._rfc4253Cache = sshbuf.toBuffer();
  128.  
  129. if (partial && typeof (partial) === 'object') {
  130. partial.remainder = sshbuf.remainder();
  131. partial.consumed = sshbuf._offset;
  132. }
  133.  
  134. return (new Constructor(key));
  135. }
  136.  
  137. function write(key, options) {
  138. assert.object(key);
  139.  
  140. var alg = keyTypeToAlg(key);
  141. var i;
  142.  
  143. var algInfo = algs.info[key.type];
  144. if (PrivateKey.isPrivateKey(key))
  145. algInfo = algs.privInfo[key.type];
  146. var parts = algInfo.parts;
  147.  
  148. var buf = new SSHBuffer({});
  149.  
  150. buf.writeString(alg);
  151.  
  152. for (i = 0; i < parts.length; ++i) {
  153. var data = key.part[parts[i]].data;
  154. if (algInfo.normalize !== false) {
  155. if (key.type === 'ed25519')
  156. data = utils.zeroPadToLength(data, 32);
  157. else
  158. data = utils.mpNormalize(data);
  159. }
  160. if (key.type === 'ed25519' && parts[i] === 'k')
  161. data = Buffer.concat([data, key.part.A.data]);
  162. buf.writeBuffer(data);
  163. }
  164.  
  165. return (buf.toBuffer());
  166. }
Buy Me A Coffee