3 // vim: set filetype=javascript :
4 // Copyright 2015 Joyent, Inc. All rights reserved.
6 var dashdash = require('dashdash');
7 var sshpk = require('../lib/index');
8 var fs = require('fs');
9 var path = require('path');
10 var tty = require('tty');
11 var readline = require('readline');
12 var getPassword = require('getpass').getPass;
16 names: ['outformat', 't'],
21 names: ['informat', 'T'],
28 help: 'Input file name (default stdin)'
33 help: 'Output file name (default stdout)'
36 names: ['private', 'p'],
38 help: 'Produce a private key as output'
41 names: ['derive', 'd'],
43 help: 'Output a new key derived from this one, with given algo'
46 names: ['identify', 'i'],
48 help: 'Print key metadata instead of converting'
51 names: ['comment', 'c'],
53 help: 'Set key comment, if output format supports'
58 help: 'Shows this help text'
62 if (require.main === module) {
63 var parser = dashdash.createParser({
68 var opts = parser.parse(process.argv);
70 console.error('sshpk-conv: error: %s', e.message);
74 if (opts.help || opts._args.length > 1) {
75 var help = parser.help({}).trimRight();
76 console.error('sshpk-conv: converts between SSH key formats\n');
78 console.error('\navailable formats:');
79 console.error(' - pem, pkcs1 eg id_rsa');
80 console.error(' - ssh eg id_rsa.pub');
81 console.error(' - pkcs8 format you want for openssl');
82 console.error(' - openssh like output of ssh-keygen -o');
83 console.error(' - rfc4253 raw OpenSSH wire format');
88 * Key derivation can only be done on private keys, so use of the -d
89 * option necessarily implies -p.
94 var inFile = process.stdin;
95 var inFileName = 'stdin';
99 inFilePath = opts.file;
100 } else if (opts._args.length === 1) {
101 inFilePath = opts._args[0];
105 inFileName = path.basename(inFilePath);
109 fs.accessSync(inFilePath, fs.R_OK);
110 inFile = fs.createReadStream(inFilePath);
113 console.error('sshpk-conv: error opening input file' +
114 ': ' + e.name + ': ' + e.message);
118 var outFile = process.stdout;
121 if (opts.out && !opts.identify) {
122 fs.accessSync(path.dirname(opts.out), fs.W_OK);
123 outFile = fs.createWriteStream(opts.out);
126 console.error('sshpk-conv: error opening output file' +
127 ': ' + e.name + ': ' + e.message);
132 inFile.on('readable', function () {
134 while ((data = inFile.read()))
138 parseOpts.filename = inFileName;
139 inFile.on('end', function processKey() {
140 var buf = Buffer.concat(bufs);
144 var f = sshpk.parseKey;
146 f = sshpk.parsePrivateKey;
148 var key = f(buf, fmt, parseOpts);
150 if (e.name === 'KeyEncryptedError') {
151 getPassword(function (err, pw) {
153 console.log('sshpk-conv: ' +
158 parseOpts.passphrase = pw;
163 console.error('sshpk-conv: ' +
164 e.name + ': ' + e.message);
169 key = key.derive(opts.derive);
172 key.comment = opts.comment;
174 if (!opts.identify) {
177 fmt = opts.outformat;
178 outFile.write(key.toBuffer(fmt));
180 (!opts.private && fmt === undefined))
182 outFile.once('drain', function () {
187 if (sshpk.PrivateKey.isPrivateKey(key))
189 console.log('%s: a %d bit %s %s key', inFileName,
190 key.size, key.type.toUpperCase(), kind);
191 if (key.type === 'ecdsa')
192 console.log('ECDSA curve: %s', key.curve);
194 console.log('Comment: %s', key.comment);
195 console.log('Fingerprint:');
196 console.log(' ' + key.fingerprint().toString());
197 console.log(' ' + key.fingerprint('md5').toString());