Sorry, the diff of this file is not supported yet
+99
-4
@@ -12,5 +12,9 @@ // Copyright 2018 Joyent, Inc. | ||
| var Key = require('../key'); | ||
| var SSHBuffer = require('../ssh-buffer'); | ||
| var crypto = require('crypto'); | ||
| var PrivateKey = require('../private-key'); | ||
| var errors = require('../errors'); | ||
| // https://tartarus.org/~simon/putty-prerel-snapshots/htmldoc/AppendixC.html | ||
| function read(buf, options) { | ||
@@ -21,8 +25,14 @@ var lines = buf.toString('ascii').split(/[\r\n]+/); | ||
| var si = 0; | ||
| var formatVersion; | ||
| while (si < lines.length) { | ||
| parts = splitHeader(lines[si++]); | ||
| if (parts && | ||
| parts[0].toLowerCase() === 'putty-user-key-file-2') { | ||
| found = true; | ||
| break; | ||
| if (parts) { | ||
| formatVersion = { | ||
| 'putty-user-key-file-2': 2, | ||
| 'putty-user-key-file-3': 3 | ||
| }[parts[0].toLowerCase()]; | ||
| if (formatVersion) { | ||
| found = true; | ||
| break; | ||
| } | ||
| } | ||
@@ -37,2 +47,3 @@ } | ||
| assert.equal(parts[0].toLowerCase(), 'encryption'); | ||
| var encryption = parts[1]; | ||
@@ -58,2 +69,74 @@ parts = splitHeader(lines[si++]); | ||
| } | ||
| si += publicLines; | ||
| if (lines[si]) { | ||
| parts = splitHeader(lines[si++]); | ||
| assert.equal(parts[0].toLowerCase(), 'private-lines'); | ||
| var privateLines = parseInt(parts[1], 10); | ||
| if (!isFinite(privateLines) || privateLines < 0 || | ||
| privateLines > lines.length) { | ||
| throw (new Error('Invalid private-lines count')); | ||
| } | ||
| var privateBuf = Buffer.from( | ||
| lines.slice(si, si + privateLines).join(''), 'base64'); | ||
| if (encryption !== 'none' && formatVersion === 3) { | ||
| throw new Error('Encrypted keys arenot supported for' + | ||
| ' PuTTY format version 3'); | ||
| } | ||
| if (encryption === 'aes256-cbc') { | ||
| if (!options.passphrase) { | ||
| throw (new errors.KeyEncryptedError( | ||
| options.filename, 'PEM')); | ||
| } | ||
| var iv = Buffer.alloc(16, 0); | ||
| var decipher = crypto.createDecipheriv( | ||
| 'aes-256-cbc', | ||
| derivePPK2EncryptionKey(options.passphrase), | ||
| iv); | ||
| decipher.setAutoPadding(false); | ||
| privateBuf = Buffer.concat([ | ||
| decipher.update(privateBuf), decipher.final()]); | ||
| } | ||
| key = new PrivateKey(key); | ||
| if (key.type !== keyType) { | ||
| throw (new Error('Outer key algorithm mismatch')); | ||
| } | ||
| var sshbuf = new SSHBuffer({buffer: privateBuf}); | ||
| var privateKeyParts; | ||
| if (alg === 'ssh-dss') { | ||
| privateKeyParts = [ { | ||
| name: 'x', | ||
| data: sshbuf.readBuffer() | ||
| }]; | ||
| } else if (alg === 'ssh-rsa') { | ||
| privateKeyParts = [ | ||
| { name: 'd', data: sshbuf.readBuffer() }, | ||
| { name: 'p', data: sshbuf.readBuffer() }, | ||
| { name: 'q', data: sshbuf.readBuffer() }, | ||
| { name: 'iqmp', data: sshbuf.readBuffer() } | ||
| ]; | ||
| } else if (alg.match(/^ecdsa-sha2-nistp/)) { | ||
| privateKeyParts = [ { | ||
| name: 'd', data: sshbuf.readBuffer() | ||
| } ]; | ||
| } else if (alg === 'ssh-ed25519') { | ||
| privateKeyParts = [ { | ||
| name: 'k', data: sshbuf.readBuffer() | ||
| } ]; | ||
| } else { | ||
| throw new Error('Unsupported PPK key type: ' + alg); | ||
| } | ||
| key = new PrivateKey({ | ||
| type: key.type, | ||
| parts: key.parts.concat(privateKeyParts) | ||
| }); | ||
| } | ||
| key.comment = comment; | ||
@@ -63,2 +146,14 @@ return (key); | ||
| function derivePPK2EncryptionKey(passphrase) { | ||
| var hash1 = crypto.createHash('sha1').update(Buffer.concat([ | ||
| Buffer.from([0, 0, 0, 0]), | ||
| Buffer.from(passphrase) | ||
| ])).digest(); | ||
| var hash2 = crypto.createHash('sha1').update(Buffer.concat([ | ||
| Buffer.from([0, 0, 0, 1]), | ||
| Buffer.from(passphrase) | ||
| ])).digest(); | ||
| return (Buffer.concat([hash1, hash2]).slice(0, 32)); | ||
| } | ||
| function splitHeader(line) { | ||
@@ -65,0 +160,0 @@ var idx = line.indexOf(':'); |
@@ -36,2 +36,3 @@ // Copyright 2017 Joyent, Inc. | ||
| formats['dnssec'] = require('./formats/dnssec'); | ||
| formats['putty'] = require('./formats/putty'); | ||
@@ -38,0 +39,0 @@ function PrivateKey(opts) { |
+1
-1
| { | ||
| "name": "sshpk", | ||
| "version": "1.16.1", | ||
| "version": "1.17.0", | ||
| "description": "A library for finding and using SSH public keys", | ||
@@ -5,0 +5,0 @@ "main": "lib/index.js", |
Sorry, the diff of this file is not supported yet
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
230511
2.23%5947
1.47%1
Infinity%