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 "-s bits Key size in bits, should be a multiple of 8 (optional)\n"
82 " DSS has a fixed size of 1024 bits\n"
86 #ifdef DROPBEAR_ECC_256
89 #ifdef DROPBEAR_ECC_384
92 #ifdef DROPBEAR_ECC_521
97 "-y Just print the publickey and fingerprint for the\n private key in <filename>.\n"
105 static void check_signkey_bits(enum signkey_type type
, int bits
)
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"
117 case DROPBEAR_SIGNKEY_DSS
:
119 dropbear_exit("DSS keys have a fixed size of 1024 bits\n");
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
) {
132 int main(int argc
, char ** argv
) {
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;
147 /* get the commandline options */
148 for (i
= 1; i
< argc
; i
++) {
149 if (argv
[i
] == NULL
) {
150 continue; /* Whack */
158 if (argv
[i
][0] == '-') {
159 switch (argv
[i
][1]) {
182 fprintf(stderr
, "Unknown argument %s\n", argv
[i
]);
191 fprintf(stderr
, "Must specify a key filename\n");
197 int ret
= printpubfile(filename
);
201 /* check/parse args */
203 fprintf(stderr
, "Must specify key type\n");
209 if (strcmp(typetext
, "rsa") == 0)
211 keytype
= DROPBEAR_SIGNKEY_RSA
;
215 if (strcmp(typetext
, "dss") == 0)
217 keytype
= DROPBEAR_SIGNKEY_DSS
;
220 #ifdef DROPBEAR_ECDSA
221 if (strcmp(typetext
, "ecdsa") == 0)
223 keytype
= DROPBEAR_SIGNKEY_ECDSA_KEYGEN
;
227 if (keytype
== DROPBEAR_SIGNKEY_NONE
) {
228 fprintf(stderr
, "Unknown key type '%s'\n", typetext
);
234 if (sscanf(sizetext
, "%u", &bits
) != 1) {
235 fprintf(stderr
, "Bits must be an integer\n");
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
);
254 static int printpubfile(const char* filename
) {
257 sign_key
*key
= NULL
;
258 enum signkey_type keytype
;
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
);
270 key
= new_sign_key();
271 keytype
= DROPBEAR_SIGNKEY_ANY
;
274 ret
= buf_get_priv_key(buf
, key
, &keytype
);
275 if (ret
== DROPBEAR_FAILURE
) {
276 fprintf(stderr
, "Bad key in '%s'\n", filename
);
280 printpubkey(key
, keytype
);
282 err
= DROPBEAR_SUCCESS
;
295 static void printpubkey(sign_key
* key
, int keytype
) {
298 unsigned char base64key
[MAX_PUBKEY_SIZE
*2];
299 unsigned long base64len
;
301 const char * typestring
= NULL
;
304 struct passwd
* pw
= NULL
;
305 char * username
= NULL
;
308 buf
= buf_new(MAX_PUBKEY_SIZE
);
309 buf_put_pub_key(buf
, key
, keytype
);
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 */
327 pw
= getpwuid(getuid());
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
);