Correct PPTP server firewall rules chain.
[tomato/davidwu.git] / release / src / router / dropbear / dropbearkey.c
blob1eb4db2f4afb524fd1639b03991b9da05bb56aea
1 /*
2 * Dropbear - a SSH2 server
3 *
4 * Copyright (c) 2002,2003 Matt Johnston
5 * All rights reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE. */
25 /* The format of the keyfiles is basically a raw dump of the buffer. Data types
26 * are specified in the transport rfc 4253 - string is a 32-bit len then the
27 * non-null-terminated string, mp_int is a 32-bit len then the bignum data.
28 * The actual functions are buf_put_rsa_priv_key() and buf_put_dss_priv_key()
30 * RSA:
31 * string "ssh-rsa"
32 * mp_int e
33 * mp_int n
34 * mp_int d
35 * mp_int p (newer versions only)
36 * mp_int q (newer versions only)
38 * DSS:
39 * string "ssh-dss"
40 * mp_int p
41 * mp_int q
42 * mp_int g
43 * mp_int y
44 * mp_int x
47 #include "includes.h"
48 #include "signkey.h"
49 #include "buffer.h"
50 #include "dbutil.h"
52 #include "genrsa.h"
53 #include "gendss.h"
54 #include "ecdsa.h"
55 #include "crypto_desc.h"
56 #include "dbrandom.h"
57 #include "gensignkey.h"
59 static void printhelp(char * progname);
62 static void printpubkey(sign_key * key, int keytype);
63 static int printpubfile(const char* filename);
65 /* Print a help message */
66 static void printhelp(char * progname) {
68 fprintf(stderr, "Usage: %s -t <type> -f <filename> [-s bits]\n"
69 "-t type Type of key to generate. One of:\n"
70 #ifdef DROPBEAR_RSA
71 " rsa\n"
72 #endif
73 #ifdef DROPBEAR_DSS
74 " dss\n"
75 #endif
76 #ifdef DROPBEAR_ECDSA
77 " ecdsa\n"
78 #endif
79 "-f filename Use filename for the secret key\n"
80 "-s bits Key size in bits, should be a multiple of 8 (optional)\n"
81 #ifdef DROPBEAR_DSS
82 " DSS has a fixed size of 1024 bits\n"
83 #endif
84 #ifdef DROPBEAR_ECDSA
85 " ECDSA has sizes "
86 #ifdef DROPBEAR_ECC_256
87 "256 "
88 #endif
89 #ifdef DROPBEAR_ECC_384
90 "384 "
91 #endif
92 #ifdef DROPBEAR_ECC_521
93 "521 "
94 #endif
95 "\n"
96 #endif
97 "-y Just print the publickey and fingerprint for the\n private key in <filename>.\n"
98 #ifdef DEBUG_TRACE
99 "-v verbose\n"
100 #endif
101 ,progname);
104 /* fails fatally */
105 static void check_signkey_bits(enum signkey_type type, int bits)
107 switch (type) {
108 #ifdef DROPBEAR_RSA
109 case DROPBEAR_SIGNKEY_RSA:
110 if (bits < 512 || bits > 4096 || (bits % 8 != 0)) {
111 dropbear_exit("Bits must satisfy 512 <= bits <= 4096, and be a"
112 " multiple of 8\n");
114 break;
115 #endif
116 #ifdef DROPEAR_DSS
117 case DROPBEAR_SIGNKEY_DSS:
118 if (bits != 1024) {
119 dropbear_exit("DSS keys have a fixed size of 1024 bits\n");
120 exit(EXIT_FAILURE);
122 #endif
123 default:
124 (void)0; /* quiet, compiler. ecdsa handles checks itself */
128 #if defined(DBMULTI_dropbearkey) || !defined(DROPBEAR_MULTI)
129 #if defined(DBMULTI_dropbearkey) && defined(DROPBEAR_MULTI)
130 int dropbearkey_main(int argc, char ** argv) {
131 #else
132 int main(int argc, char ** argv) {
133 #endif
135 int i;
136 char ** next = 0;
137 char * filename = NULL;
138 enum signkey_type keytype = DROPBEAR_SIGNKEY_NONE;
139 char * typetext = NULL;
140 char * sizetext = NULL;
141 unsigned int bits = 0;
142 int printpub = 0;
144 crypto_init();
145 seedrandom();
147 /* get the commandline options */
148 for (i = 1; i < argc; i++) {
149 if (argv[i] == NULL) {
150 continue; /* Whack */
152 if (next) {
153 *next = argv[i];
154 next = NULL;
155 continue;
158 if (argv[i][0] == '-') {
159 switch (argv[i][1]) {
160 case 'f':
161 next = &filename;
162 break;
163 case 't':
164 next = &typetext;
165 break;
166 case 's':
167 next = &sizetext;
168 break;
169 case 'y':
170 printpub = 1;
171 break;
172 case 'h':
173 printhelp(argv[0]);
174 exit(EXIT_SUCCESS);
175 break;
176 #ifdef DEBUG_TRACE
177 case 'v':
178 debug_trace = 1;
179 break;
180 #endif
181 default:
182 fprintf(stderr, "Unknown argument %s\n", argv[i]);
183 printhelp(argv[0]);
184 exit(EXIT_FAILURE);
185 break;
190 if (!filename) {
191 fprintf(stderr, "Must specify a key filename\n");
192 printhelp(argv[0]);
193 exit(EXIT_FAILURE);
196 if (printpub) {
197 int ret = printpubfile(filename);
198 exit(ret);
201 /* check/parse args */
202 if (!typetext) {
203 fprintf(stderr, "Must specify key type\n");
204 printhelp(argv[0]);
205 exit(EXIT_FAILURE);
208 #ifdef DROPBEAR_RSA
209 if (strcmp(typetext, "rsa") == 0)
211 keytype = DROPBEAR_SIGNKEY_RSA;
213 #endif
214 #ifdef DROPBEAR_DSS
215 if (strcmp(typetext, "dss") == 0)
217 keytype = DROPBEAR_SIGNKEY_DSS;
219 #endif
220 #ifdef DROPBEAR_ECDSA
221 if (strcmp(typetext, "ecdsa") == 0)
223 keytype = DROPBEAR_SIGNKEY_ECDSA_KEYGEN;
225 #endif
227 if (keytype == DROPBEAR_SIGNKEY_NONE) {
228 fprintf(stderr, "Unknown key type '%s'\n", typetext);
229 printhelp(argv[0]);
230 exit(EXIT_FAILURE);
233 if (sizetext) {
234 if (sscanf(sizetext, "%u", &bits) != 1) {
235 fprintf(stderr, "Bits must be an integer\n");
236 exit(EXIT_FAILURE);
239 check_signkey_bits(keytype, bits);;
242 fprintf(stderr, "Generating key, this may take a while...\n");
243 if (signkey_generate(keytype, bits, filename) == DROPBEAR_FAILURE)
245 dropbear_exit("Failed to generate key.\n");
248 printpubfile(filename);
250 return EXIT_SUCCESS;
252 #endif
254 static int printpubfile(const char* filename) {
256 buffer *buf = NULL;
257 sign_key *key = NULL;
258 enum signkey_type keytype;
259 int ret;
260 int err = DROPBEAR_FAILURE;
262 buf = buf_new(MAX_PRIVKEY_SIZE);
263 ret = buf_readfile(buf, filename);
265 if (ret != DROPBEAR_SUCCESS) {
266 fprintf(stderr, "Failed reading '%s'\n", filename);
267 goto out;
270 key = new_sign_key();
271 keytype = DROPBEAR_SIGNKEY_ANY;
273 buf_setpos(buf, 0);
274 ret = buf_get_priv_key(buf, key, &keytype);
275 if (ret == DROPBEAR_FAILURE) {
276 fprintf(stderr, "Bad key in '%s'\n", filename);
277 goto out;
280 printpubkey(key, keytype);
282 err = DROPBEAR_SUCCESS;
284 out:
285 buf_burn(buf);
286 buf_free(buf);
287 buf = NULL;
288 if (key) {
289 sign_key_free(key);
290 key = NULL;
292 return err;
295 static void printpubkey(sign_key * key, int keytype) {
297 buffer * buf = NULL;
298 unsigned char base64key[MAX_PUBKEY_SIZE*2];
299 unsigned long base64len;
300 int err;
301 const char * typestring = NULL;
302 char *fp = NULL;
303 int len;
304 struct passwd * pw = NULL;
305 char * username = NULL;
306 char hostname[100];
308 buf = buf_new(MAX_PUBKEY_SIZE);
309 buf_put_pub_key(buf, key, keytype);
310 buf_setpos(buf, 4);
312 len = buf->len - buf->pos;
314 base64len = sizeof(base64key);
315 err = base64_encode(buf_getptr(buf, len), len, base64key, &base64len);
317 if (err != CRYPT_OK) {
318 fprintf(stderr, "base64 failed");
321 typestring = signkey_name_from_type(keytype, NULL);
323 fp = sign_key_fingerprint(buf_getptr(buf, len), len);
325 /* a user@host comment is informative */
326 username = "";
327 pw = getpwuid(getuid());
328 if (pw) {
329 username = pw->pw_name;
332 gethostname(hostname, sizeof(hostname));
333 hostname[sizeof(hostname)-1] = '\0';
335 printf("Public key portion is:\n%s %s %s@%s\nFingerprint: %s\n",
336 typestring, base64key, username, hostname, fp);
338 m_free(fp);
339 buf_free(buf);