8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / cmd / cmd-crypto / kmfcfg / create.c
blobe399205613a91b5c80940bd2454c768a02637326
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
21 * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
24 #include <stdio.h>
25 #include <strings.h>
26 #include <ctype.h>
27 #include <libgen.h>
28 #include <libintl.h>
29 #include <errno.h>
30 #include <kmfapiP.h>
31 #include <cryptoutil.h>
32 #include "util.h"
34 int
35 kc_create(int argc, char *argv[])
37 KMF_RETURN ret;
38 int rv = KC_OK;
39 int opt;
40 extern int optind_av;
41 extern char *optarg_av;
42 char *filename = NULL;
43 int ocsp_set_attr = 0;
44 boolean_t crl_set_attr = 0;
45 KMF_POLICY_RECORD plc;
47 (void) memset(&plc, 0, sizeof (KMF_POLICY_RECORD));
49 while ((opt = getopt_av(argc, argv,
50 "i:(dbfile)"
51 "p:(policy)"
52 "d:(ignore-date)"
53 "e:(ignore-unknown-eku)"
54 "a:(ignore-trust-anchor)"
55 "v:(validity-adjusttime)"
56 "t:(ta-name)"
57 "s:(ta-serial)"
58 "o:(ocsp-responder)"
59 "P:(ocsp-proxy)"
60 "r:(ocsp-use-cert-responder)"
61 "T:(ocsp-response-lifetime)"
62 "R:(ocsp-ignore-response-sign)"
63 "n:(ocsp-responder-cert-name)"
64 "A:(ocsp-responder-cert-serial)"
65 "c:(crl-basefilename)"
66 "I:(crl-directory)"
67 "g:(crl-get-crl-uri)"
68 "X:(crl-proxy)"
69 "S:(crl-ignore-crl-sign)"
70 "D:(crl-ignore-crl-date)"
71 "m:(mapper-name)"
72 "M:(mapper-directory)"
73 "Q:(mapper-pathname)"
74 "q:(mapper-options)"
75 "u:(keyusage)"
76 "E:(ekunames)"
77 "O:(ekuoids)")) != EOF) {
78 switch (opt) {
79 case 'i':
80 filename = get_string(optarg_av, &rv);
81 if (filename == NULL) {
82 (void) fprintf(stderr,
83 gettext("Error dbfile input.\n"));
85 break;
86 case 'p':
87 plc.name = get_string(optarg_av, &rv);
88 if (plc.name == NULL) {
89 (void) fprintf(stderr,
90 gettext("Error policy name.\n"));
92 break;
93 case 'd':
94 plc.ignore_date = get_boolean(optarg_av);
95 if (plc.ignore_date == -1) {
96 (void) fprintf(stderr,
97 gettext("Error boolean input.\n"));
98 rv = KC_ERR_USAGE;
100 break;
101 case 'e':
102 plc.ignore_unknown_ekus =
103 get_boolean(optarg_av);
104 if (plc.ignore_unknown_ekus == -1) {
105 (void) fprintf(stderr,
106 gettext("Error boolean input.\n"));
107 rv = KC_ERR_USAGE;
109 break;
110 case 'a':
111 plc.ignore_trust_anchor =
112 get_boolean(optarg_av);
113 if (plc.ignore_trust_anchor == -1) {
114 (void) fprintf(stderr,
115 gettext("Error boolean input.\n"));
116 rv = KC_ERR_USAGE;
118 break;
119 case 'v':
120 plc.validity_adjusttime =
121 get_string(optarg_av, &rv);
122 if (plc.validity_adjusttime == NULL) {
123 (void) fprintf(stderr,
124 gettext("Error time input.\n"));
125 } else {
126 uint32_t adj;
127 /* for syntax checking */
128 if (str2lifetime(
129 plc.validity_adjusttime,
130 &adj) < 0) {
131 (void) fprintf(stderr,
132 gettext("Error time "
133 "input.\n"));
134 rv = KC_ERR_USAGE;
137 break;
138 case 't':
139 plc.ta_name = get_string(optarg_av, &rv);
140 if (plc.ta_name == NULL) {
141 (void) fprintf(stderr,
142 gettext("Error name input.\n"));
143 } else if (strcasecmp(plc.ta_name,
144 "search") != 0) {
145 KMF_X509_NAME taDN;
146 /* for syntax checking */
147 if (kmf_dn_parser(plc.ta_name,
148 &taDN) != KMF_OK) {
149 (void) fprintf(stderr,
150 gettext("Error name "
151 "input.\n"));
152 rv = KC_ERR_USAGE;
153 } else {
154 kmf_free_dn(&taDN);
157 break;
158 case 's':
159 plc.ta_serial = get_string(optarg_av, &rv);
160 if (plc.ta_serial == NULL) {
161 (void) fprintf(stderr,
162 gettext("Error serial input.\n"));
163 } else {
164 uchar_t *bytes = NULL;
165 size_t bytelen;
167 ret = kmf_hexstr_to_bytes(
168 (uchar_t *)plc.ta_serial,
169 &bytes, &bytelen);
170 if (ret != KMF_OK || bytes == NULL) {
171 (void) fprintf(stderr,
172 gettext("serial number "
173 "must be specified as a "
174 "hex number "
175 "(ex: 0x0102030405"
176 "ffeeddee)\n"));
177 rv = KC_ERR_USAGE;
179 if (bytes != NULL)
180 free(bytes);
182 break;
183 case 'o':
184 plc.VAL_OCSP_RESPONDER_URI =
185 get_string(optarg_av, &rv);
186 if (plc.VAL_OCSP_RESPONDER_URI == NULL) {
187 (void) fprintf(stderr, gettext(
188 "Error responder input.\n"));
189 } else {
190 ocsp_set_attr++;
192 break;
193 case 'P':
194 plc.VAL_OCSP_PROXY =
195 get_string(optarg_av, &rv);
196 if (plc.VAL_OCSP_PROXY == NULL) {
197 (void) fprintf(stderr,
198 gettext("Error proxy input.\n"));
199 } else {
200 ocsp_set_attr++;
202 break;
203 case 'r':
204 plc.VAL_OCSP_URI_FROM_CERT =
205 get_boolean(optarg_av);
206 if (plc.VAL_OCSP_URI_FROM_CERT == -1) {
207 (void) fprintf(stderr,
208 gettext("Error boolean input.\n"));
209 rv = KC_ERR_USAGE;
210 } else {
211 ocsp_set_attr++;
213 break;
214 case 'T':
215 plc.VAL_OCSP_RESP_LIFETIME =
216 get_string(optarg_av, &rv);
217 if (plc.VAL_OCSP_RESP_LIFETIME == NULL) {
218 (void) fprintf(stderr,
219 gettext("Error time input.\n"));
220 } else {
221 uint32_t adj;
222 /* for syntax checking */
223 if (str2lifetime(
224 plc.VAL_OCSP_RESP_LIFETIME,
225 &adj) < 0) {
226 (void) fprintf(stderr,
227 gettext("Error time "
228 "input.\n"));
229 rv = KC_ERR_USAGE;
230 } else {
231 ocsp_set_attr++;
234 break;
235 case 'R':
236 plc.VAL_OCSP_IGNORE_RESP_SIGN =
237 get_boolean(optarg_av);
238 if (plc.VAL_OCSP_IGNORE_RESP_SIGN == -1) {
239 (void) fprintf(stderr,
240 gettext("Error boolean input.\n"));
241 rv = KC_ERR_USAGE;
242 } else {
243 ocsp_set_attr++;
245 break;
246 case 'n':
247 plc.VAL_OCSP_RESP_CERT_NAME =
248 get_string(optarg_av, &rv);
249 if (plc.VAL_OCSP_RESP_CERT_NAME == NULL) {
250 (void) fprintf(stderr,
251 gettext("Error name input.\n"));
252 } else {
253 KMF_X509_NAME respDN;
254 /* for syntax checking */
255 if (kmf_dn_parser(
256 plc.VAL_OCSP_RESP_CERT_NAME,
257 &respDN) != KMF_OK) {
258 (void) fprintf(stderr,
259 gettext("Error name "
260 "input.\n"));
261 rv = KC_ERR_USAGE;
262 } else {
263 kmf_free_dn(&respDN);
264 ocsp_set_attr++;
267 break;
268 case 'A':
269 plc.VAL_OCSP_RESP_CERT_SERIAL =
270 get_string(optarg_av, &rv);
271 if (plc.VAL_OCSP_RESP_CERT_SERIAL == NULL) {
272 (void) fprintf(stderr,
273 gettext("Error serial input.\n"));
274 } else {
275 uchar_t *bytes = NULL;
276 size_t bytelen;
278 ret = kmf_hexstr_to_bytes((uchar_t *)
279 plc.VAL_OCSP_RESP_CERT_SERIAL,
280 &bytes, &bytelen);
281 if (ret != KMF_OK || bytes == NULL) {
282 (void) fprintf(stderr,
283 gettext("serial number "
284 "must be specified as a "
285 "hex number "
286 "(ex: 0x0102030405"
287 "ffeeddee)\n"));
288 rv = KC_ERR_USAGE;
289 break;
291 if (bytes != NULL)
292 free(bytes);
293 ocsp_set_attr++;
295 break;
296 case 'c':
297 plc.VAL_CRL_BASEFILENAME =
298 get_string(optarg_av, &rv);
299 if (plc.VAL_CRL_BASEFILENAME == NULL) {
300 (void) fprintf(stderr,
301 gettext("Error boolean input.\n"));
302 } else {
303 crl_set_attr++;
305 break;
306 case 'I':
307 plc.VAL_CRL_DIRECTORY =
308 get_string(optarg_av, &rv);
309 if (plc.VAL_CRL_DIRECTORY == NULL) {
310 (void) fprintf(stderr,
311 gettext("Error boolean input.\n"));
312 } else {
313 crl_set_attr++;
315 break;
316 case 'g':
317 plc.VAL_CRL_GET_URI = get_boolean(optarg_av);
318 if (plc.VAL_CRL_GET_URI == -1) {
319 (void) fprintf(stderr,
320 gettext("Error boolean input.\n"));
321 rv = KC_ERR_USAGE;
322 } else {
323 crl_set_attr++;
325 break;
326 case 'X':
327 plc.VAL_CRL_PROXY = get_string(optarg_av, &rv);
328 if (plc.VAL_CRL_PROXY == NULL) {
329 (void) fprintf(stderr,
330 gettext("Error proxy input.\n"));
331 } else {
332 crl_set_attr++;
334 break;
335 case 'S':
336 plc.VAL_CRL_IGNORE_SIGN =
337 get_boolean(optarg_av);
338 if (plc.VAL_CRL_IGNORE_SIGN == -1) {
339 (void) fprintf(stderr,
340 gettext("Error boolean input.\n"));
341 rv = KC_ERR_USAGE;
342 } else {
343 crl_set_attr++;
345 break;
346 case 'D':
347 plc.VAL_CRL_IGNORE_DATE =
348 get_boolean(optarg_av);
349 if (plc.VAL_CRL_IGNORE_DATE == -1) {
350 (void) fprintf(stderr,
351 gettext("Error boolean input.\n"));
352 rv = KC_ERR_USAGE;
353 } else {
354 crl_set_attr++;
356 break;
357 case 'u':
358 plc.ku_bits = parseKUlist(optarg_av);
359 if (plc.ku_bits == 0) {
360 (void) fprintf(stderr, gettext(
361 "Error keyusage input.\n"));
362 rv = KC_ERR_USAGE;
364 break;
365 case 'E':
366 if (parseEKUNames(optarg_av, &plc) != 0) {
367 (void) fprintf(stderr,
368 gettext("Error EKU input.\n"));
369 rv = KC_ERR_USAGE;
371 break;
372 case 'O':
373 if (parseEKUOIDs(optarg_av, &plc) != 0) {
374 (void) fprintf(stderr,
375 gettext("Error EKU OID input.\n"));
376 rv = KC_ERR_USAGE;
378 break;
379 case 'm':
380 plc.mapper.mapname = get_string(optarg_av, &rv);
381 if (plc.mapper.mapname == NULL) {
382 (void) fprintf(stderr,
383 gettext("Error mapper-name "
384 "input.\n"));
386 break;
387 case 'M':
388 plc.mapper.dir = get_string(optarg_av, &rv);
389 if (plc.mapper.dir == NULL) {
390 (void) fprintf(stderr,
391 gettext("Error mapper-dir "
392 "input.\n"));
394 break;
395 case 'Q':
396 plc.mapper.pathname = get_string(optarg_av,
397 &rv);
398 if (plc.mapper.pathname == NULL) {
399 (void) fprintf(stderr,
400 gettext("Error mapper-pathname "
401 "input.\n"));
403 break;
404 case 'q':
405 plc.mapper.options = get_string(optarg_av, &rv);
406 if (plc.mapper.options == NULL) {
407 (void) fprintf(stderr,
408 gettext("Error mapper-options "
409 "input.\n"));
411 break;
412 default:
413 (void) fprintf(stderr,
414 gettext("Error input option.\n"));
415 rv = KC_ERR_USAGE;
416 break;
419 if (rv != KC_OK)
420 goto out;
423 /* No additional args allowed. */
424 argc -= optind_av;
425 if (argc) {
426 (void) fprintf(stderr,
427 gettext("Error input option\n"));
428 rv = KC_ERR_USAGE;
429 goto out;
432 if (filename == NULL) {
433 filename = strdup(KMF_DEFAULT_POLICY_FILE);
434 if (filename == NULL) {
435 rv = KC_ERR_MEMORY;
436 goto out;
441 * Must have a policy name. The policy name can not be default
442 * if using the default policy file.
444 if (plc.name == NULL) {
445 (void) fprintf(stderr,
446 gettext("You must specify a policy name\n"));
447 rv = KC_ERR_USAGE;
448 goto out;
449 } else if (strcmp(filename, KMF_DEFAULT_POLICY_FILE) == 0 &&
450 strcmp(plc.name, KMF_DEFAULT_POLICY_NAME) == 0) {
451 (void) fprintf(stderr,
452 gettext("Can not create a default policy in the default "
453 "policy file\n"));
454 rv = KC_ERR_USAGE;
455 goto out;
459 * If the policy file exists and the policy is in the policy file
460 * already, we will not create it again.
462 if (access(filename, R_OK) == 0) {
463 POLICY_LIST *plclist = NULL, *pnode;
464 int found = 0;
466 rv = load_policies(filename, &plclist);
467 if (rv != KMF_OK)
468 goto out;
470 pnode = plclist;
471 while (pnode != NULL && !found) {
472 if (strcmp(plc.name, pnode->plc.name) == 0)
473 found++;
474 pnode = pnode->next;
476 free_policy_list(plclist);
478 if (found) {
479 (void) fprintf(stderr,
480 gettext("Could not create policy \"%s\" - exists "
481 "already\n"), plc.name);
482 rv = KC_ERR_USAGE;
483 goto out;
488 * If any OCSP attribute is set, turn on the OCSP checking flag.
489 * Also set "has_resp_cert" to be true, if the responder cert
490 * is provided.
492 if (ocsp_set_attr > 0)
493 plc.revocation |= KMF_REVOCATION_METHOD_OCSP;
495 if (plc.VAL_OCSP_RESP_CERT.name != NULL &&
496 plc.VAL_OCSP_RESP_CERT.serial != NULL) {
497 plc.VAL_OCSP.has_resp_cert = B_TRUE;
501 * Setting mapper-name (with optional mapper-dir) and mapper-pathname is
502 * mutually exclusive. Also, you cannot set options only, you need the
503 * name or pathname, and you can set the directory only with the name,
504 * not the pathname.
506 if ((plc.mapper.mapname != NULL && plc.mapper.pathname != NULL) ||
507 (plc.mapper.dir != NULL && plc.mapper.pathname != NULL) ||
508 (plc.mapper.dir != NULL && plc.mapper.mapname == NULL) ||
509 (plc.mapper.options != NULL && plc.mapper.mapname == NULL &&
510 plc.mapper.pathname == NULL)) {
511 (void) fprintf(stderr,
512 gettext("Error in mapper input options\n"));
513 rv = KC_ERR_USAGE;
514 goto out;
518 * If any CRL attribute is set, turn on the CRL checking flag.
520 if (crl_set_attr > 0)
521 plc.revocation |= KMF_REVOCATION_METHOD_CRL;
524 * Does a sanity check on the new policy.
526 ret = kmf_verify_policy(&plc);
527 if (ret != KMF_OK) {
528 print_sanity_error(ret);
529 rv = KC_ERR_ADD_POLICY;
530 goto out;
534 * Add to the DB.
536 ret = kmf_add_policy_to_db(&plc, filename, B_FALSE);
537 if (ret != KMF_OK) {
538 (void) fprintf(stderr,
539 gettext("Error adding policy to database: 0x%04x\n"), ret);
540 rv = KC_ERR_ADD_POLICY;
543 out:
544 if (filename != NULL)
545 free(filename);
547 kmf_free_policy_record(&plc);
549 return (rv);