Initial commit
[yaffs-website] / node_modules / sshpk / bin / sshpk-conv
1 #!/usr/bin/env node
2 // -*- mode: js -*-
3 // vim: set filetype=javascript :
4 // Copyright 2015 Joyent, Inc.  All rights reserved.
5
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;
13
14 var options = [
15         {
16                 names: ['outformat', 't'],
17                 type: 'string',
18                 help: 'Output format'
19         },
20         {
21                 names: ['informat', 'T'],
22                 type: 'string',
23                 help: 'Input format'
24         },
25         {
26                 names: ['file', 'f'],
27                 type: 'string',
28                 help: 'Input file name (default stdin)'
29         },
30         {
31                 names: ['out', 'o'],
32                 type: 'string',
33                 help: 'Output file name (default stdout)'
34         },
35         {
36                 names: ['private', 'p'],
37                 type: 'bool',
38                 help: 'Produce a private key as output'
39         },
40         {
41                 names: ['derive', 'd'],
42                 type: 'string',
43                 help: 'Output a new key derived from this one, with given algo'
44         },
45         {
46                 names: ['identify', 'i'],
47                 type: 'bool',
48                 help: 'Print key metadata instead of converting'
49         },
50         {
51                 names: ['comment', 'c'],
52                 type: 'string',
53                 help: 'Set key comment, if output format supports'
54         },
55         {
56                 names: ['help', 'h'],
57                 type: 'bool',
58                 help: 'Shows this help text'
59         }
60 ];
61
62 if (require.main === module) {
63         var parser = dashdash.createParser({
64                 options: options
65         });
66
67         try {
68                 var opts = parser.parse(process.argv);
69         } catch (e) {
70                 console.error('sshpk-conv: error: %s', e.message);
71                 process.exit(1);
72         }
73
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');
77                 console.error(help);
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');
84                 process.exit(1);
85         }
86
87         /*
88          * Key derivation can only be done on private keys, so use of the -d
89          * option necessarily implies -p.
90          */
91         if (opts.derive)
92                 opts.private = true;
93
94         var inFile = process.stdin;
95         var inFileName = 'stdin';
96
97         var inFilePath;
98         if (opts.file) {
99                 inFilePath = opts.file;
100         } else if (opts._args.length === 1) {
101                 inFilePath = opts._args[0];
102         }
103
104         if (inFilePath)
105                 inFileName = path.basename(inFilePath);
106
107         try {
108                 if (inFilePath) {
109                         fs.accessSync(inFilePath, fs.R_OK);
110                         inFile = fs.createReadStream(inFilePath);
111                 }
112         } catch (e) {
113                 console.error('sshpk-conv: error opening input file' +
114                      ': ' + e.name + ': ' + e.message);
115                 process.exit(1);
116         }
117
118         var outFile = process.stdout;
119
120         try {
121                 if (opts.out && !opts.identify) {
122                         fs.accessSync(path.dirname(opts.out), fs.W_OK);
123                         outFile = fs.createWriteStream(opts.out);
124                 }
125         } catch (e) {
126                 console.error('sshpk-conv: error opening output file' +
127                     ': ' + e.name + ': ' + e.message);
128                 process.exit(1);
129         }
130
131         var bufs = [];
132         inFile.on('readable', function () {
133                 var data;
134                 while ((data = inFile.read()))
135                         bufs.push(data);
136         });
137         var parseOpts = {};
138         parseOpts.filename = inFileName;
139         inFile.on('end', function processKey() {
140                 var buf = Buffer.concat(bufs);
141                 var fmt = 'auto';
142                 if (opts.informat)
143                         fmt = opts.informat;
144                 var f = sshpk.parseKey;
145                 if (opts.private)
146                         f = sshpk.parsePrivateKey;
147                 try {
148                         var key = f(buf, fmt, parseOpts);
149                 } catch (e) {
150                         if (e.name === 'KeyEncryptedError') {
151                                 getPassword(function (err, pw) {
152                                         if (err) {
153                                                 console.log('sshpk-conv: ' +
154                                                     err.name + ': ' +
155                                                     err.message);
156                                                 process.exit(1);
157                                         }
158                                         parseOpts.passphrase = pw;
159                                         processKey();
160                                 });
161                                 return;
162                         }
163                         console.error('sshpk-conv: ' +
164                             e.name + ': ' + e.message);
165                         process.exit(1);
166                 }
167
168                 if (opts.derive)
169                         key = key.derive(opts.derive);
170
171                 if (opts.comment)
172                         key.comment = opts.comment;
173
174                 if (!opts.identify) {
175                         fmt = undefined;
176                         if (opts.outformat)
177                                 fmt = opts.outformat;
178                         outFile.write(key.toBuffer(fmt));
179                         if (fmt === 'ssh' ||
180                             (!opts.private && fmt === undefined))
181                                 outFile.write('\n');
182                         outFile.once('drain', function () {
183                                 process.exit(0);
184                         });
185                 } else {
186                         var kind = 'public';
187                         if (sshpk.PrivateKey.isPrivateKey(key))
188                                 kind = 'private';
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);
193                         if (key.comment)
194                                 console.log('Comment: %s', key.comment);
195                         console.log('Fingerprint:');
196                         console.log('  ' + key.fingerprint().toString());
197                         console.log('  ' + key.fingerprint('md5').toString());
198                         process.exit(0);
199                 }
200         });
201 }