corrected usage
[strongswan.git] / src / pki / commands / req.c
1 /*
2 * Copyright (C) 2009 Martin Willi
3 * Copyright (C) 2009 Andreas Steffen
4 *
5 * HSR Hochschule fuer Technik Rapperswil
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 * for more details.
16 */
17
18 #include <time.h>
19
20 #include "pki.h"
21
22 #include <utils/linked_list.h>
23 #include <credentials/certificates/certificate.h>
24
25 /**
26 * Create a self-signed PKCS#10 certificate requesst.
27 */
28 static int req()
29 {
30 key_type_t type = KEY_RSA;
31 hash_algorithm_t digest = HASH_SHA1;
32 certificate_t *cert = NULL;
33 private_key_t *private = NULL;
34 char *file = NULL, *dn = NULL, *error = NULL;
35 identification_t *id = NULL;
36 linked_list_t *san;
37 chunk_t encoding = chunk_empty;
38 chunk_t challenge_password = chunk_empty;
39 char *arg;
40
41 san = linked_list_create();
42
43 while (TRUE)
44 {
45 switch (command_getopt(&arg))
46 {
47 case 'h':
48 goto usage;
49 case 'v':
50 dbg_level = atoi(arg);
51 continue;
52 case 't':
53 if (streq(arg, "rsa"))
54 {
55 type = KEY_RSA;
56 }
57 else if (streq(arg, "ecdsa"))
58 {
59 type = KEY_ECDSA;
60 }
61 else
62 {
63 error = "invalid input type";
64 goto usage;
65 }
66 continue;
67 case 'g':
68 digest = get_digest(arg);
69 if (digest == HASH_UNKNOWN)
70 {
71 error = "invalid --digest type";
72 goto usage;
73 }
74 continue;
75 case 'i':
76 file = arg;
77 continue;
78 case 'd':
79 dn = arg;
80 continue;
81 case 'a':
82 san->insert_last(san, identification_create_from_string(arg));
83 continue;
84 case 'p':
85 challenge_password = chunk_create(arg, strlen(arg));
86 continue;
87 case EOF:
88 break;
89 default:
90 error = "invalid --req option";
91 goto usage;
92 }
93 break;
94 }
95
96 if (!dn)
97 {
98 error = "--dn is required";
99 goto usage;
100 }
101 id = identification_create_from_string(dn);
102 if (id->get_type(id) != ID_DER_ASN1_DN)
103 {
104 error = "supplied --dn is not a distinguished name";
105 goto end;
106 }
107 if (file)
108 {
109 private = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, type,
110 BUILD_FROM_FILE, file, BUILD_END);
111 }
112 else
113 {
114 private = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, type,
115 BUILD_FROM_FD, 0, BUILD_END);
116 }
117 if (!private)
118 {
119 error = "parsing private key failed";
120 goto end;
121 }
122 cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_PKCS10_REQUEST,
123 BUILD_SIGNING_KEY, private,
124 BUILD_SUBJECT, id,
125 BUILD_SUBJECT_ALTNAMES, san,
126 BUILD_PASSPHRASE, challenge_password,
127 BUILD_DIGEST_ALG, digest,
128 BUILD_END);
129 if (!cert)
130 {
131 error = "generating certificate request failed";
132 goto end;
133 }
134 encoding = cert->get_encoding(cert);
135 if (!encoding.ptr)
136 {
137 error = "encoding certificate request failed";
138 goto end;
139 }
140 if (fwrite(encoding.ptr, encoding.len, 1, stdout) != 1)
141 {
142 error = "writing certificate request failed";
143 goto end;
144 }
145
146 end:
147 DESTROY_IF(id);
148 DESTROY_IF(cert);
149 DESTROY_IF(private);
150 san->destroy_offset(san, offsetof(identification_t, destroy));
151 free(encoding.ptr);
152
153 if (error)
154 {
155 fprintf(stderr, "%s\n", error);
156 return 1;
157 }
158 return 0;
159
160 usage:
161 san->destroy_offset(san, offsetof(identification_t, destroy));
162 return command_usage(error);
163 }
164
165 /**
166 * Register the command.
167 */
168 static void __attribute__ ((constructor))reg()
169 {
170 command_register((command_t) {
171 req, 'r', "req",
172 "create a PKCS#10 certificate request",
173 {"[--in file] [--type rsa|ecdsa]",
174 " --dn distinguished-name [--san subjectAltName]+",
175 "[--password challengePassword]",
176 "[--digest md5|sha1|sha224|sha256|sha384|sha512]"},
177 {
178 {"help", 'h', 0, "show usage information"},
179 {"in", 'i', 1, "private key input file, default: stdin"},
180 {"type", 't', 1, "type of input key, default: rsa"},
181 {"dn", 'd', 1, "subject distinguished name"},
182 {"san", 'a', 1, "subjectAltName to include in cert request"},
183 {"password",'p', 1, "challengePassword to include in cert request"},
184 {"digest", 'g', 1, "digest for signature creation, default: sha1"},
185 }
186 });
187 }