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 draft - 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)
56 static void printhelp(char * progname);
60 #define RSA_SIZE (1024/8) /* 1024 bit */
61 #define DSS_SIZE (1024/8) /* 1024 bit */
63 static void buf_writefile(buffer * buf, 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"
70 "-t type Type of key to generate. One of:\n"
77 "-f filename Use filename for the secret key\n"
78 "-s bits Key size in bits, should be "
79 "multiple of 8 (optional)\n",
83 int main(int argc, char ** argv) {
89 char * filename = NULL;
91 char * typetext = NULL;
92 char * sizetext = NULL;
96 /* get the commandline options */
97 for (i = 1; i < argc; i++) {
101 fprintf(stderr, "Invalid null argument");
107 if (argv[i][0] == '-') {
108 switch (argv[i][1]) {
123 fprintf(stderr, "Unknown argument %s\n", argv[i]);
131 /* check/parse args */
133 fprintf(stderr, "Must specify file type, one of:\n"
146 if (strlen(typetext) == 3) {
148 if (strncmp(typetext, "rsa", 3) == 0) {
149 keytype = DROPBEAR_SIGNKEY_RSA;
150 TRACE(("type is rsa"));
154 if (strncmp(typetext, "dss", 3) == 0) {
155 keytype = DROPBEAR_SIGNKEY_DSS;
156 TRACE(("type is dss"));
161 fprintf(stderr, "Unknown key type '%s'\n", typetext);
167 if (sscanf(sizetext, "%u", &bits) != 1) {
168 fprintf(stderr, "Bits must be an integer\n");
172 if (bits < 512 || bits > 4096 || (bits % 8 != 0)) {
173 fprintf(stderr, "Bits must satisfy 512 <= bits <= 4096, and be a"
180 if (keytype == DROPBEAR_SIGNKEY_DSS) {
182 } else if (keytype == DROPBEAR_SIGNKEY_RSA) {
185 exit(EXIT_FAILURE); /* not reached */
190 fprintf(stderr, "Must specify a key filename\n");
195 fprintf(stderr, "Will output %d bit %s secret key to '%s'\n", keysize*8,
198 /* don't want the file readable by others */
201 /* now we can generate the key */
202 key = new_sign_key();
204 fprintf(stderr, "Generating key, this may take a while...\n");
207 case DROPBEAR_SIGNKEY_RSA:
208 key->rsakey = gen_rsa_priv_key(keysize); /* 128 bytes = 1024 bit */
212 case DROPBEAR_SIGNKEY_DSS:
213 key->dsskey = gen_dss_priv_key(keysize); /* 128 bytes = 1024 bit */
217 fprintf(stderr, "Internal error, bad key type\n");
221 buf = buf_new(BUF_SIZE);
223 buf_put_priv_key(buf, key, keytype);
225 buf_writefile(buf, filename);
231 fprintf(stderr, "Done.\n");
236 /* Write a buffer to a file specified, failing if the file exists */
237 static void buf_writefile(buffer * buf, const char * filename) {
242 fd = open(filename, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
244 fprintf(stderr, "Couldn't create new file %s\n", filename);
250 /* write the file now */
251 while (buf->pos != buf->len) {
252 len = write(fd, buf_getptr(buf, buf->len - buf->pos),
253 buf->len - buf->pos);
254 if (errno == EINTR) {
258 fprintf(stderr, "Failed writing file '%s'\n",filename);
262 buf_incrpos(buf, len);