ce28a097110a527e2d0880489fe189755fcd01ce
[strongswan.git] / src / pki / commands / gen.c
1 /*
2 * Copyright (C) 2009 Martin Willi
3 * Hochschule fuer Technik Rapperswil
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16 #include "pki.h"
17
18 /**
19 * Generate a private key
20 */
21 static int gen()
22 {
23 cred_encoding_type_t form = PRIVKEY_ASN1_DER;
24 key_type_t type = KEY_RSA;
25 u_int size = 0, shares = 0, threshold = 1;
26 private_key_t *key;
27 chunk_t encoding;
28 bool safe_primes = FALSE;
29 char *arg;
30
31 while (TRUE)
32 {
33 switch (command_getopt(&arg))
34 {
35 case 'h':
36 return command_usage(NULL);
37 case 't':
38 if (streq(arg, "rsa"))
39 {
40 type = KEY_RSA;
41 }
42 else if (streq(arg, "ecdsa"))
43 {
44 type = KEY_ECDSA;
45 }
46 else
47 {
48 return command_usage("invalid key type");
49 }
50 continue;
51 case 'f':
52 if (!get_form(arg, &form, CRED_PRIVATE_KEY))
53 {
54 return command_usage("invalid key output format");
55 }
56 continue;
57 case 's':
58 size = atoi(arg);
59 if (!size)
60 {
61 return command_usage("invalid key size");
62 }
63 continue;
64 case 'p':
65 safe_primes = TRUE;
66 continue;
67 case 'n':
68 shares = atoi(arg);
69 if (shares < 2)
70 {
71 return command_usage("invalid number of key shares");
72 }
73 continue;
74 case 'l':
75 threshold = atoi(arg);
76 if (threshold < 1)
77 {
78 return command_usage("invalid key share threshold");
79 }
80 continue;
81 case EOF:
82 break;
83 default:
84 return command_usage("invalid --gen option");
85 }
86 break;
87 }
88 /* default key sizes */
89 if (!size)
90 {
91 switch (type)
92 {
93 case KEY_RSA:
94 size = 2048;
95 break;
96 case KEY_ECDSA:
97 size = 384;
98 break;
99 default:
100 break;
101 }
102 }
103 if (type == KEY_RSA && shares)
104 {
105 if (threshold > shares)
106 {
107 return command_usage("threshold is larger than number of shares");
108 }
109 key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, type,
110 BUILD_KEY_SIZE, size, BUILD_SAFE_PRIMES,
111 BUILD_SHARES, shares, BUILD_THRESHOLD, threshold,
112 BUILD_END);
113 }
114 else if (type == KEY_RSA && safe_primes)
115 {
116 key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, type,
117 BUILD_KEY_SIZE, size, BUILD_SAFE_PRIMES, BUILD_END);
118 }
119 else
120 {
121 key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, type,
122 BUILD_KEY_SIZE, size, BUILD_END);
123 }
124 if (!key)
125 {
126 fprintf(stderr, "private key generation failed\n");
127 return 1;
128 }
129 if (!key->get_encoding(key, form, &encoding))
130 {
131 fprintf(stderr, "private key encoding failed\n");
132 key->destroy(key);
133 return 1;
134 }
135 key->destroy(key);
136 set_file_mode(stdout, form);
137 if (fwrite(encoding.ptr, encoding.len, 1, stdout) != 1)
138 {
139 fprintf(stderr, "writing private key failed\n");
140 free(encoding.ptr);
141 return 1;
142 }
143 free(encoding.ptr);
144 return 0;
145 }
146
147 /**
148 * Register the command.
149 */
150 static void __attribute__ ((constructor))reg()
151 {
152 command_register((command_t) {
153 gen, 'g', "gen", "generate a new private key",
154 {" [--type rsa|ecdsa] [--size bits] [--safe-primes]",
155 "[--shares n] [--threshold l] [--outform der|pem]"},
156 {
157 {"help", 'h', 0, "show usage information"},
158 {"type", 't', 1, "type of key, default: rsa"},
159 {"size", 's', 1, "keylength in bits, default: rsa 2048, ecdsa 384"},
160 {"safe-primes", 'p', 0, "generate rsa safe primes"},
161 {"shares", 'n', 1, "number of private rsa key shares"},
162 {"threshold", 'l', 1, "minimum number of participating rsa key shares"},
163 {"outform", 'f', 1, "encoding of generated private key, default: der"},
164 }
165 });
166 }