Created framework for BLISS post-quantum signature algorithm
[strongswan.git] / src / pki / commands / gen.c
1 /*
2 * Copyright (C) 2009 Martin Willi
3 * Copyright (C) 2014 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, "bliss"))
48 {
49 type = KEY_BLISS;
50 }
51 else
52 {
53 return command_usage("invalid key type");
54 }
55 continue;
56 case 'f':
57 if (!get_form(arg, &form, CRED_PRIVATE_KEY))
58 {
59 return command_usage("invalid key output format");
60 }
61 continue;
62 case 's':
63 size = atoi(arg);
64 if (!size)
65 {
66 return command_usage("invalid key size");
67 }
68 continue;
69 case 'p':
70 safe_primes = TRUE;
71 continue;
72 case 'n':
73 shares = atoi(arg);
74 if (shares < 2)
75 {
76 return command_usage("invalid number of key shares");
77 }
78 continue;
79 case 'l':
80 threshold = atoi(arg);
81 if (threshold < 1)
82 {
83 return command_usage("invalid key share threshold");
84 }
85 continue;
86 case EOF:
87 break;
88 default:
89 return command_usage("invalid --gen option");
90 }
91 break;
92 }
93 /* default key sizes */
94 if (!size)
95 {
96 switch (type)
97 {
98 case KEY_RSA:
99 size = 2048;
100 break;
101 case KEY_ECDSA:
102 size = 384;
103 break;
104 case KEY_BLISS:
105 size = 1;
106 break;
107 default:
108 break;
109 }
110 }
111 if (type == KEY_RSA && shares)
112 {
113 if (threshold > shares)
114 {
115 return command_usage("threshold is larger than number of shares");
116 }
117 key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, type,
118 BUILD_KEY_SIZE, size, BUILD_SAFE_PRIMES,
119 BUILD_SHARES, shares, BUILD_THRESHOLD, threshold,
120 BUILD_END);
121 }
122 else if (type == KEY_RSA && safe_primes)
123 {
124 key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, type,
125 BUILD_KEY_SIZE, size, BUILD_SAFE_PRIMES, BUILD_END);
126 }
127 else
128 {
129 key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, type,
130 BUILD_KEY_SIZE, size, BUILD_END);
131 }
132 if (!key)
133 {
134 fprintf(stderr, "private key generation failed\n");
135 return 1;
136 }
137 if (!key->get_encoding(key, form, &encoding))
138 {
139 fprintf(stderr, "private key encoding failed\n");
140 key->destroy(key);
141 return 1;
142 }
143 key->destroy(key);
144 set_file_mode(stdout, form);
145 if (fwrite(encoding.ptr, encoding.len, 1, stdout) != 1)
146 {
147 fprintf(stderr, "writing private key failed\n");
148 free(encoding.ptr);
149 return 1;
150 }
151 free(encoding.ptr);
152 return 0;
153 }
154
155 /**
156 * Register the command.
157 */
158 static void __attribute__ ((constructor))reg()
159 {
160 command_register((command_t) {
161 gen, 'g', "gen", "generate a new private key",
162 {" [--type rsa|ecdsa|bliss] [--size bits] [--safe-primes]",
163 "[--shares n] [--threshold l] [--outform der|pem]"},
164 {
165 {"help", 'h', 0, "show usage information"},
166 {"type", 't', 1, "type of key, default: rsa"},
167 {"size", 's', 1, "keylength in bits, default: rsa 2048, ecdsa 384, bliss 1"},
168 {"safe-primes", 'p', 0, "generate rsa safe primes"},
169 {"shares", 'n', 1, "number of private rsa key shares"},
170 {"threshold", 'l', 1, "minimum number of participating rsa key shares"},
171 {"outform", 'f', 1, "encoding of generated private key, default: der"},
172 }
173 });
174 }