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