2 * Dropbear - a SSH2 server
4 * Copyright (c) 2002,2003 Matt Johnston
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
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()
35 * mp_int p (newer versions only)
36 * mp_int q (newer versions only)
55 #include "crypto_desc.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"
79 "-f filename Use filename for the secret key.\n"
80 " ~/.ssh/id_dropbear is recommended for client keys.\n"
81 "-s bits Key size in bits, should be a multiple of 8 (optional)\n"
83 " DSS has a fixed size of 1024 bits\n"
87 #ifdef DROPBEAR_ECC_256
90 #ifdef DROPBEAR_ECC_384
93 #ifdef DROPBEAR_ECC_521
98 "-y Just print the publickey and fingerprint for the\n private key in <filename>.\n"
106 static void check_signkey_bits(enum signkey_type type
, int bits
)
110 case DROPBEAR_SIGNKEY_RSA
:
111 if (bits
< 512 || bits
> 4096 || (bits
% 8 != 0)) {
112 dropbear_exit("Bits must satisfy 512 <= bits <= 4096, and be a"
118 case DROPBEAR_SIGNKEY_DSS
:
120 dropbear_exit("DSS keys have a fixed size of 1024 bits\n");
125 (void)0; /* quiet, compiler. ecdsa handles checks itself */
129 #if defined(DBMULTI_dropbearkey) || !defined(DROPBEAR_MULTI)
130 #if defined(DBMULTI_dropbearkey) && defined(DROPBEAR_MULTI)
131 int dropbearkey_main(int argc
, char ** argv
) {
133 int main(int argc
, char ** argv
) {
138 char * filename
= NULL
;
139 enum signkey_type keytype
= DROPBEAR_SIGNKEY_NONE
;
140 char * typetext
= NULL
;
141 char * sizetext
= NULL
;
142 unsigned int bits
= 0;
148 /* get the commandline options */
149 for (i
= 1; i
< argc
; i
++) {
150 if (argv
[i
] == NULL
) {
151 continue; /* Whack */
159 if (argv
[i
][0] == '-') {
160 switch (argv
[i
][1]) {
183 fprintf(stderr
, "Unknown argument %s\n", argv
[i
]);
192 fprintf(stderr
, "Must specify a key filename\n");
198 int ret
= printpubfile(filename
);
202 /* check/parse args */
204 fprintf(stderr
, "Must specify key type\n");
210 if (strcmp(typetext
, "rsa") == 0)
212 keytype
= DROPBEAR_SIGNKEY_RSA
;
216 if (strcmp(typetext
, "dss") == 0)
218 keytype
= DROPBEAR_SIGNKEY_DSS
;
221 #ifdef DROPBEAR_ECDSA
222 if (strcmp(typetext
, "ecdsa") == 0)
224 keytype
= DROPBEAR_SIGNKEY_ECDSA_KEYGEN
;
228 if (keytype
== DROPBEAR_SIGNKEY_NONE
) {
229 fprintf(stderr
, "Unknown key type '%s'\n", typetext
);
235 if (sscanf(sizetext
, "%u", &bits
) != 1) {
236 fprintf(stderr
, "Bits must be an integer\n");
240 check_signkey_bits(keytype
, bits
);;
243 fprintf(stderr
, "Generating key, this may take a while...\n");
244 if (signkey_generate(keytype
, bits
, filename
) == DROPBEAR_FAILURE
)
246 dropbear_exit("Failed to generate key.\n");
249 printpubfile(filename
);
255 static int printpubfile(const char* filename
) {
258 sign_key
*key
= NULL
;
259 enum signkey_type keytype
;
261 int err
= DROPBEAR_FAILURE
;
263 buf
= buf_new(MAX_PRIVKEY_SIZE
);
264 ret
= buf_readfile(buf
, filename
);
266 if (ret
!= DROPBEAR_SUCCESS
) {
267 fprintf(stderr
, "Failed reading '%s'\n", filename
);
271 key
= new_sign_key();
272 keytype
= DROPBEAR_SIGNKEY_ANY
;
275 ret
= buf_get_priv_key(buf
, key
, &keytype
);
276 if (ret
== DROPBEAR_FAILURE
) {
277 fprintf(stderr
, "Bad key in '%s'\n", filename
);
281 printpubkey(key
, keytype
);
283 err
= DROPBEAR_SUCCESS
;
296 static void printpubkey(sign_key
* key
, int keytype
) {
299 unsigned char base64key
[MAX_PUBKEY_SIZE
*2];
300 unsigned long base64len
;
302 const char * typestring
= NULL
;
305 struct passwd
* pw
= NULL
;
306 char * username
= NULL
;
309 buf
= buf_new(MAX_PUBKEY_SIZE
);
310 buf_put_pub_key(buf
, key
, keytype
);
313 len
= buf
->len
- buf
->pos
;
315 base64len
= sizeof(base64key
);
316 err
= base64_encode(buf_getptr(buf
, len
), len
, base64key
, &base64len
);
318 if (err
!= CRYPT_OK
) {
319 fprintf(stderr
, "base64 failed");
322 typestring
= signkey_name_from_type(keytype
, NULL
);
324 fp
= sign_key_fingerprint(buf_getptr(buf
, len
), len
);
326 /* a user@host comment is informative */
328 pw
= getpwuid(getuid());
330 username
= pw
->pw_name
;
333 gethostname(hostname
, sizeof(hostname
));
334 hostname
[sizeof(hostname
)-1] = '\0';
336 printf("Public key portion is:\n%s %s %s@%s\nFingerprint: %s\n",
337 typestring
, base64key
, username
, hostname
, fp
);