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]
21 * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
31 #include <cryptoutil.h>
35 kc_create(int argc
, char *argv
[])
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
,
53 "e:(ignore-unknown-eku)"
54 "a:(ignore-trust-anchor)"
55 "v:(validity-adjusttime)"
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)"
69 "S:(crl-ignore-crl-sign)"
70 "D:(crl-ignore-crl-date)"
72 "M:(mapper-directory)"
77 "O:(ekuoids)")) != EOF
) {
80 filename
= get_string(optarg_av
, &rv
);
81 if (filename
== NULL
) {
82 (void) fprintf(stderr
,
83 gettext("Error dbfile input.\n"));
87 plc
.name
= get_string(optarg_av
, &rv
);
88 if (plc
.name
== NULL
) {
89 (void) fprintf(stderr
,
90 gettext("Error policy name.\n"));
94 plc
.ignore_date
= get_boolean(optarg_av
);
95 if (plc
.ignore_date
== -1) {
96 (void) fprintf(stderr
,
97 gettext("Error boolean input.\n"));
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"));
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"));
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"));
127 /* for syntax checking */
129 plc
.validity_adjusttime
,
131 (void) fprintf(stderr
,
132 gettext("Error time "
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
,
146 /* for syntax checking */
147 if (kmf_dn_parser(plc
.ta_name
,
149 (void) fprintf(stderr
,
150 gettext("Error name "
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"));
164 uchar_t
*bytes
= NULL
;
167 ret
= kmf_hexstr_to_bytes(
168 (uchar_t
*)plc
.ta_serial
,
170 if (ret
!= KMF_OK
|| bytes
== NULL
) {
171 (void) fprintf(stderr
,
172 gettext("serial number "
173 "must be specified as a "
183 plc
.VAL_OCSP_RESPONDER_URI
=
184 get_string(optarg_av
, &rv
);
185 if (plc
.VAL_OCSP_RESPONDER_URI
== NULL
) {
186 (void) fprintf(stderr
, gettext(
187 "Error responder input.\n"));
194 get_string(optarg_av
, &rv
);
195 if (plc
.VAL_OCSP_PROXY
== NULL
) {
196 (void) fprintf(stderr
,
197 gettext("Error proxy input.\n"));
203 plc
.VAL_OCSP_URI_FROM_CERT
=
204 get_boolean(optarg_av
);
205 if (plc
.VAL_OCSP_URI_FROM_CERT
== -1) {
206 (void) fprintf(stderr
,
207 gettext("Error boolean input.\n"));
214 plc
.VAL_OCSP_RESP_LIFETIME
=
215 get_string(optarg_av
, &rv
);
216 if (plc
.VAL_OCSP_RESP_LIFETIME
== NULL
) {
217 (void) fprintf(stderr
,
218 gettext("Error time input.\n"));
221 /* for syntax checking */
223 plc
.VAL_OCSP_RESP_LIFETIME
,
225 (void) fprintf(stderr
,
226 gettext("Error time "
235 plc
.VAL_OCSP_IGNORE_RESP_SIGN
=
236 get_boolean(optarg_av
);
237 if (plc
.VAL_OCSP_IGNORE_RESP_SIGN
== -1) {
238 (void) fprintf(stderr
,
239 gettext("Error boolean input.\n"));
246 plc
.VAL_OCSP_RESP_CERT_NAME
=
247 get_string(optarg_av
, &rv
);
248 if (plc
.VAL_OCSP_RESP_CERT_NAME
== NULL
) {
249 (void) fprintf(stderr
,
250 gettext("Error name input.\n"));
252 KMF_X509_NAME respDN
;
253 /* for syntax checking */
255 plc
.VAL_OCSP_RESP_CERT_NAME
,
256 &respDN
) != KMF_OK
) {
257 (void) fprintf(stderr
,
258 gettext("Error name "
262 kmf_free_dn(&respDN
);
268 plc
.VAL_OCSP_RESP_CERT_SERIAL
=
269 get_string(optarg_av
, &rv
);
270 if (plc
.VAL_OCSP_RESP_CERT_SERIAL
== NULL
) {
271 (void) fprintf(stderr
,
272 gettext("Error serial input.\n"));
274 uchar_t
*bytes
= NULL
;
277 ret
= kmf_hexstr_to_bytes((uchar_t
*)
278 plc
.VAL_OCSP_RESP_CERT_SERIAL
,
280 if (ret
!= KMF_OK
|| bytes
== NULL
) {
281 (void) fprintf(stderr
,
282 gettext("serial number "
283 "must be specified as a "
295 plc
.VAL_CRL_BASEFILENAME
=
296 get_string(optarg_av
, &rv
);
297 if (plc
.VAL_CRL_BASEFILENAME
== NULL
) {
298 (void) fprintf(stderr
,
299 gettext("Error boolean input.\n"));
305 plc
.VAL_CRL_DIRECTORY
=
306 get_string(optarg_av
, &rv
);
307 if (plc
.VAL_CRL_DIRECTORY
== NULL
) {
308 (void) fprintf(stderr
,
309 gettext("Error boolean input.\n"));
315 plc
.VAL_CRL_GET_URI
= get_boolean(optarg_av
);
316 if (plc
.VAL_CRL_GET_URI
== -1) {
317 (void) fprintf(stderr
,
318 gettext("Error boolean input.\n"));
325 plc
.VAL_CRL_PROXY
= get_string(optarg_av
, &rv
);
326 if (plc
.VAL_CRL_PROXY
== NULL
) {
327 (void) fprintf(stderr
,
328 gettext("Error proxy input.\n"));
334 plc
.VAL_CRL_IGNORE_SIGN
=
335 get_boolean(optarg_av
);
336 if (plc
.VAL_CRL_IGNORE_SIGN
== -1) {
337 (void) fprintf(stderr
,
338 gettext("Error boolean input.\n"));
345 plc
.VAL_CRL_IGNORE_DATE
=
346 get_boolean(optarg_av
);
347 if (plc
.VAL_CRL_IGNORE_DATE
== -1) {
348 (void) fprintf(stderr
,
349 gettext("Error boolean input.\n"));
356 plc
.ku_bits
= parseKUlist(optarg_av
);
357 if (plc
.ku_bits
== 0) {
358 (void) fprintf(stderr
, gettext(
359 "Error keyusage input.\n"));
364 if (parseEKUNames(optarg_av
, &plc
) != 0) {
365 (void) fprintf(stderr
,
366 gettext("Error EKU input.\n"));
371 if (parseEKUOIDs(optarg_av
, &plc
) != 0) {
372 (void) fprintf(stderr
,
373 gettext("Error EKU OID input.\n"));
378 plc
.mapper
.mapname
= get_string(optarg_av
, &rv
);
379 if (plc
.mapper
.mapname
== NULL
) {
380 (void) fprintf(stderr
,
381 gettext("Error mapper-name "
386 plc
.mapper
.dir
= get_string(optarg_av
, &rv
);
387 if (plc
.mapper
.dir
== NULL
) {
388 (void) fprintf(stderr
,
389 gettext("Error mapper-dir "
394 plc
.mapper
.pathname
= get_string(optarg_av
,
396 if (plc
.mapper
.pathname
== NULL
) {
397 (void) fprintf(stderr
,
398 gettext("Error mapper-pathname "
403 plc
.mapper
.options
= get_string(optarg_av
, &rv
);
404 if (plc
.mapper
.options
== NULL
) {
405 (void) fprintf(stderr
,
406 gettext("Error mapper-options "
411 (void) fprintf(stderr
,
412 gettext("Error input option.\n"));
421 /* No additional args allowed. */
424 (void) fprintf(stderr
,
425 gettext("Error input option\n"));
430 if (filename
== NULL
) {
431 filename
= strdup(KMF_DEFAULT_POLICY_FILE
);
432 if (filename
== NULL
) {
439 * Must have a policy name. The policy name can not be default
440 * if using the default policy file.
442 if (plc
.name
== NULL
) {
443 (void) fprintf(stderr
,
444 gettext("You must specify a policy name\n"));
447 } else if (strcmp(filename
, KMF_DEFAULT_POLICY_FILE
) == 0 &&
448 strcmp(plc
.name
, KMF_DEFAULT_POLICY_NAME
) == 0) {
449 (void) fprintf(stderr
,
450 gettext("Can not create a default policy in the default "
457 * If the policy file exists and the policy is in the policy file
458 * already, we will not create it again.
460 if (access(filename
, R_OK
) == 0) {
461 POLICY_LIST
*plclist
= NULL
, *pnode
;
464 rv
= load_policies(filename
, &plclist
);
469 while (pnode
!= NULL
&& !found
) {
470 if (strcmp(plc
.name
, pnode
->plc
.name
) == 0)
474 free_policy_list(plclist
);
477 (void) fprintf(stderr
,
478 gettext("Could not create policy \"%s\" - exists "
479 "already\n"), plc
.name
);
486 * If any OCSP attribute is set, turn on the OCSP checking flag.
487 * Also set "has_resp_cert" to be true, if the responder cert
490 if (ocsp_set_attr
> 0)
491 plc
.revocation
|= KMF_REVOCATION_METHOD_OCSP
;
493 if (plc
.VAL_OCSP_RESP_CERT
.name
!= NULL
&&
494 plc
.VAL_OCSP_RESP_CERT
.serial
!= NULL
) {
495 plc
.VAL_OCSP
.has_resp_cert
= B_TRUE
;
499 * Setting mapper-name (with optional mapper-dir) and mapper-pathname is
500 * mutually exclusive. Also, you cannot set options only, you need the
501 * name or pathname, and you can set the directory only with the name,
504 if ((plc
.mapper
.mapname
!= NULL
&& plc
.mapper
.pathname
!= NULL
) ||
505 (plc
.mapper
.dir
!= NULL
&& plc
.mapper
.pathname
!= NULL
) ||
506 (plc
.mapper
.dir
!= NULL
&& plc
.mapper
.mapname
== NULL
) ||
507 (plc
.mapper
.options
!= NULL
&& plc
.mapper
.mapname
== NULL
&&
508 plc
.mapper
.pathname
== NULL
)) {
509 (void) fprintf(stderr
,
510 gettext("Error in mapper input options\n"));
516 * If any CRL attribute is set, turn on the CRL checking flag.
518 if (crl_set_attr
> 0)
519 plc
.revocation
|= KMF_REVOCATION_METHOD_CRL
;
522 * Does a sanity check on the new policy.
524 ret
= kmf_verify_policy(&plc
);
526 print_sanity_error(ret
);
527 rv
= KC_ERR_ADD_POLICY
;
534 ret
= kmf_add_policy_to_db(&plc
, filename
, B_FALSE
);
536 (void) fprintf(stderr
,
537 gettext("Error adding policy to database: 0x%04x\n"), ret
);
538 rv
= KC_ERR_ADD_POLICY
;
544 kmf_free_policy_record(&plc
);