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>
33 #include <sys/param.h>
36 #define KC_IGNORE_DATE 0x0000001
37 #define KC_IGNORE_UNKNOWN_EKUS 0x0000002
38 #define KC_IGNORE_TRUST_ANCHOR 0x0000004
39 #define KC_VALIDITY_ADJUSTTIME 0x0000008
40 #define KC_TA_NAME 0x0000010
41 #define KC_TA_SERIAL 0x0000020
42 #define KC_OCSP_RESPONDER_URI 0x0000040
43 #define KC_OCSP_PROXY 0x0000080
44 #define KC_OCSP_URI_FROM_CERT 0x0000100
45 #define KC_OCSP_RESP_LIFETIME 0x0000200
46 #define KC_OCSP_IGNORE_RESP_SIGN 0x0000400
47 #define KC_OCSP_RESP_CERT_NAME 0x0000800
48 #define KC_OCSP_RESP_CERT_SERIAL 0x0001000
49 #define KC_OCSP_NONE 0x0002000
50 #define KC_CRL_BASEFILENAME 0x0004000
51 #define KC_CRL_DIRECTORY 0x0008000
52 #define KC_CRL_GET_URI 0x0010000
53 #define KC_CRL_PROXY 0x0020000
54 #define KC_CRL_IGNORE_SIGN 0x0040000
55 #define KC_CRL_IGNORE_DATE 0x0080000
56 #define KC_CRL_NONE 0x0100000
57 #define KC_KEYUSAGE 0x0200000
58 #define KC_KEYUSAGE_NONE 0x0400000
59 #define KC_EKUS 0x0800000
60 #define KC_EKUS_NONE 0x1000000
61 #define KC_MAPPER_OPTIONS 0x2000000
63 static int err
; /* To store errno which may be overwritten by gettext() */
65 #define UPDATE_IF_DIFFERENT(old, new) \
66 if ((old != NULL && new != NULL && strcmp(old, new) != 0) || \
67 (old == NULL && new != NULL)) { \
73 kc_modify_policy(int argc
, char *argv
[])
79 extern char *optarg_av
;
80 char *filename
= NULL
;
81 char *mapper_name
= NULL
;
82 char *mapper_dir
= NULL
;
83 char *mapper_pathname
= NULL
;
85 boolean_t ocsp_none_opt
= B_FALSE
;
86 boolean_t crl_none_opt
= B_FALSE
;
87 boolean_t ku_none_opt
= B_FALSE
;
88 boolean_t eku_none_opt
= B_FALSE
;
89 int ocsp_set_attr
= 0;
91 KMF_POLICY_RECORD oplc
, plc
;
93 (void) memset(&plc
, 0, sizeof (KMF_POLICY_RECORD
));
94 (void) memset(&oplc
, 0, sizeof (KMF_POLICY_RECORD
));
96 while ((opt
= getopt_av(argc
, argv
,
100 "e:(ignore-unknown-eku)"
101 "a:(ignore-trust-anchor)"
102 "v:(validity-adjusttime)"
107 "r:(ocsp-use-cert-responder)"
108 "T:(ocsp-response-lifetime)"
109 "R:(ocsp-ignore-response-sign)"
110 "n:(ocsp-responder-cert-name)"
111 "A:(ocsp-responder-cert-serial)"
113 "c:(crl-basefilename)"
115 "g:(crl-get-crl-uri)"
117 "S:(crl-ignore-crl-sign)"
118 "D:(crl-ignore-crl-date)"
125 "M:(mapper-directory)"
126 "Q:(mapper-pathname)"
128 "Z:(eku-none)")) != EOF
) {
131 filename
= get_string(optarg_av
, &rv
);
132 if (filename
== NULL
) {
133 (void) fprintf(stderr
,
134 gettext("Error dbfile input.\n"));
138 plc
.name
= get_string(optarg_av
, &rv
);
139 if (plc
.name
== NULL
) {
140 (void) fprintf(stderr
,
141 gettext("Error policy name.\n"));
145 plc
.ignore_date
= get_boolean(optarg_av
);
146 if (plc
.ignore_date
== -1) {
147 (void) fprintf(stderr
,
148 gettext("Error boolean input.\n"));
151 flags
|= KC_IGNORE_DATE
;
155 plc
.ignore_unknown_ekus
=
156 get_boolean(optarg_av
);
157 if (plc
.ignore_unknown_ekus
== -1) {
158 (void) fprintf(stderr
,
159 gettext("Error boolean input.\n"));
162 flags
|= KC_IGNORE_UNKNOWN_EKUS
;
166 plc
.ignore_trust_anchor
=
167 get_boolean(optarg_av
);
168 if (plc
.ignore_trust_anchor
== -1) {
169 (void) fprintf(stderr
,
170 gettext("Error boolean input.\n"));
173 flags
|= KC_IGNORE_TRUST_ANCHOR
;
177 plc
.validity_adjusttime
=
178 get_string(optarg_av
, &rv
);
179 if (plc
.validity_adjusttime
== NULL
) {
180 (void) fprintf(stderr
,
181 gettext("Error time input.\n"));
184 /* for syntax checking */
186 plc
.validity_adjusttime
,
188 (void) fprintf(stderr
,
189 gettext("Error time "
193 flags
|= KC_VALIDITY_ADJUSTTIME
;
198 plc
.ta_name
= get_string(optarg_av
, &rv
);
199 if (plc
.ta_name
== NULL
) {
200 (void) fprintf(stderr
,
201 gettext("Error name input.\n"));
202 } else if (strcasecmp(plc
.ta_name
, "search")) {
204 /* for syntax checking */
205 if (kmf_dn_parser(plc
.ta_name
,
207 (void) fprintf(stderr
,
208 gettext("Error name "
220 plc
.ta_serial
= get_string(optarg_av
, &rv
);
221 if (plc
.ta_serial
== NULL
) {
222 (void) fprintf(stderr
,
223 gettext("Error serial input.\n"));
225 uchar_t
*bytes
= NULL
;
228 ret
= kmf_hexstr_to_bytes(
229 (uchar_t
*)plc
.ta_serial
,
231 if (ret
!= KMF_OK
|| bytes
== NULL
) {
232 (void) fprintf(stderr
,
233 gettext("serial number "
234 "must be specified as a "
242 flags
|= KC_TA_SERIAL
;
246 plc
.VAL_OCSP_RESPONDER_URI
=
247 get_string(optarg_av
, &rv
);
248 if (plc
.VAL_OCSP_RESPONDER_URI
== NULL
) {
249 (void) fprintf(stderr
,
250 gettext("Error responder "
253 flags
|= KC_OCSP_RESPONDER_URI
;
258 plc
.VAL_OCSP_PROXY
= get_string(optarg_av
, &rv
);
259 if (plc
.VAL_OCSP_PROXY
== NULL
) {
260 (void) fprintf(stderr
,
261 gettext("Error proxy input.\n"));
263 flags
|= KC_OCSP_PROXY
;
268 plc
.VAL_OCSP_URI_FROM_CERT
=
269 get_boolean(optarg_av
);
270 if (plc
.VAL_OCSP_URI_FROM_CERT
== -1) {
271 (void) fprintf(stderr
,
272 gettext("Error boolean input.\n"));
275 flags
|= KC_OCSP_URI_FROM_CERT
;
280 plc
.VAL_OCSP_RESP_LIFETIME
=
281 get_string(optarg_av
, &rv
);
282 if (plc
.VAL_OCSP_RESP_LIFETIME
== NULL
) {
283 (void) fprintf(stderr
,
284 gettext("Error time input.\n"));
287 /* for syntax checking */
289 plc
.VAL_OCSP_RESP_LIFETIME
,
291 (void) fprintf(stderr
,
292 gettext("Error time "
296 flags
|= KC_OCSP_RESP_LIFETIME
;
302 plc
.VAL_OCSP_IGNORE_RESP_SIGN
=
303 get_boolean(optarg_av
);
304 if (plc
.VAL_OCSP_IGNORE_RESP_SIGN
== -1) {
305 (void) fprintf(stderr
,
306 gettext("Error boolean input.\n"));
309 flags
|= KC_OCSP_IGNORE_RESP_SIGN
;
314 plc
.VAL_OCSP_RESP_CERT_NAME
=
315 get_string(optarg_av
, &rv
);
316 if (plc
.VAL_OCSP_RESP_CERT_NAME
== NULL
) {
317 (void) fprintf(stderr
,
318 gettext("Error name input.\n"));
320 KMF_X509_NAME respDN
;
321 /* for syntax checking */
323 plc
.VAL_OCSP_RESP_CERT_NAME
,
324 &respDN
) != KMF_OK
) {
325 (void) fprintf(stderr
,
326 gettext("Error name "
330 kmf_free_dn(&respDN
);
331 flags
|= KC_OCSP_RESP_CERT_NAME
;
337 plc
.VAL_OCSP_RESP_CERT_SERIAL
=
338 get_string(optarg_av
, &rv
);
339 if (plc
.VAL_OCSP_RESP_CERT_SERIAL
== NULL
) {
340 (void) fprintf(stderr
,
341 gettext("Error serial input.\n"));
343 uchar_t
*bytes
= NULL
;
346 ret
= kmf_hexstr_to_bytes((uchar_t
*)
347 plc
.VAL_OCSP_RESP_CERT_SERIAL
,
349 if (ret
!= KMF_OK
|| bytes
== NULL
) {
350 (void) fprintf(stderr
,
351 gettext("serial number "
352 "must be specified as a "
360 flags
|= KC_OCSP_RESP_CERT_SERIAL
;
365 ocsp_none_opt
= get_boolean(optarg_av
);
366 if (ocsp_none_opt
== -1) {
367 (void) fprintf(stderr
,
368 gettext("Error boolean input.\n"));
371 flags
|= KC_OCSP_NONE
;
375 plc
.VAL_CRL_BASEFILENAME
=
376 get_string(optarg_av
, &rv
);
377 if (plc
.VAL_CRL_BASEFILENAME
== NULL
) {
378 (void) fprintf(stderr
, gettext(
379 "Error basefilename input.\n"));
381 flags
|= KC_CRL_BASEFILENAME
;
386 plc
.VAL_CRL_DIRECTORY
=
387 get_string(optarg_av
, &rv
);
388 if (plc
.VAL_CRL_DIRECTORY
== NULL
) {
389 (void) fprintf(stderr
,
390 gettext("Error boolean input.\n"));
392 flags
|= KC_CRL_DIRECTORY
;
397 plc
.VAL_CRL_GET_URI
= get_boolean(optarg_av
);
398 if (plc
.VAL_CRL_GET_URI
== -1) {
399 (void) fprintf(stderr
,
400 gettext("Error boolean input.\n"));
403 flags
|= KC_CRL_GET_URI
;
408 plc
.VAL_CRL_PROXY
= get_string(optarg_av
, &rv
);
409 if (plc
.VAL_CRL_PROXY
== NULL
) {
410 (void) fprintf(stderr
,
411 gettext("Error proxy input.\n"));
413 flags
|= KC_CRL_PROXY
;
418 plc
.VAL_CRL_IGNORE_SIGN
=
419 get_boolean(optarg_av
);
420 if (plc
.VAL_CRL_IGNORE_SIGN
== -1) {
421 (void) fprintf(stderr
,
422 gettext("Error boolean input.\n"));
425 flags
|= KC_CRL_IGNORE_SIGN
;
430 plc
.VAL_CRL_IGNORE_DATE
=
431 get_boolean(optarg_av
);
432 if (plc
.VAL_CRL_IGNORE_DATE
== -1) {
433 (void) fprintf(stderr
,
434 gettext("Error boolean input.\n"));
437 flags
|= KC_CRL_IGNORE_DATE
;
442 crl_none_opt
= get_boolean(optarg_av
);
443 if (crl_none_opt
== -1) {
444 (void) fprintf(stderr
,
445 gettext("Error boolean input.\n"));
448 flags
|= KC_CRL_NONE
;
452 plc
.ku_bits
= parseKUlist(optarg_av
);
453 if (plc
.ku_bits
== 0) {
454 (void) fprintf(stderr
, gettext(
455 "Error keyusage input.\n"));
458 flags
|= KC_KEYUSAGE
;
462 ku_none_opt
= get_boolean(optarg_av
);
463 if (ku_none_opt
== -1) {
464 (void) fprintf(stderr
,
465 gettext("Error boolean input.\n"));
468 flags
|= KC_KEYUSAGE_NONE
;
472 if (parseEKUNames(optarg_av
, &plc
) != 0) {
473 (void) fprintf(stderr
,
474 gettext("Error EKU input.\n"));
481 if (parseEKUOIDs(optarg_av
, &plc
) != 0) {
482 (void) fprintf(stderr
,
483 gettext("Error EKU OID input.\n"));
490 eku_none_opt
= get_boolean(optarg_av
);
491 if (eku_none_opt
== -1) {
492 (void) fprintf(stderr
,
493 gettext("Error boolean input.\n"));
496 flags
|= KC_EKUS_NONE
;
500 mapper_name
= get_string(optarg_av
, &rv
);
501 if (mapper_name
== NULL
) {
502 (void) fprintf(stderr
,
503 gettext("Error mapper-name "
508 mapper_dir
= get_string(optarg_av
, &rv
);
509 if (mapper_dir
== NULL
) {
510 (void) fprintf(stderr
,
511 gettext("Error mapper-directory "
516 mapper_pathname
= get_string(optarg_av
, &rv
);
517 if (mapper_pathname
== NULL
) {
518 (void) fprintf(stderr
,
519 gettext("Error mapper-pathname "
524 plc
.mapper
.options
= get_string(optarg_av
, &rv
);
525 rv
= 0; /* its ok for this to be NULL */
526 flags
|= KC_MAPPER_OPTIONS
;
529 (void) fprintf(stderr
,
530 gettext("Error input option.\n"));
538 /* No additional args allowed. */
541 (void) fprintf(stderr
,
542 gettext("Error input option\n"));
547 if (filename
== NULL
) {
548 filename
= strdup(KMF_DEFAULT_POLICY_FILE
);
549 if (filename
== NULL
) {
556 * Must have a policy name. The policy name can not be default
557 * if using the default policy file.
559 if (plc
.name
== NULL
) {
560 (void) fprintf(stderr
,
561 gettext("You must specify a policy name.\n"));
564 } else if (strcmp(filename
, KMF_DEFAULT_POLICY_FILE
) == 0 &&
565 strcmp(plc
.name
, KMF_DEFAULT_POLICY_NAME
) == 0) {
566 (void) fprintf(stderr
,
567 gettext("Can not modify the default policy in the default "
573 /* Check the access permission of the policy DB */
574 if (access(filename
, W_OK
) < 0) {
576 (void) fprintf(stderr
,
577 gettext("Cannot access \"%s\" for modify - %s\n"),
578 filename
, strerror(err
));
583 /* Try to load the named policy from the DB */
584 ret
= kmf_get_policy(filename
, plc
.name
, &oplc
);
586 (void) fprintf(stderr
,
587 gettext("Error loading policy \"%s\" from %s\n"), filename
,
589 return (KC_ERR_FIND_POLICY
);
592 /* Update the general policy attributes. */
593 if (flags
& KC_IGNORE_DATE
)
594 oplc
.ignore_date
= plc
.ignore_date
;
596 if (flags
& KC_IGNORE_UNKNOWN_EKUS
)
597 oplc
.ignore_unknown_ekus
= plc
.ignore_unknown_ekus
;
599 if (flags
& KC_IGNORE_TRUST_ANCHOR
)
600 oplc
.ignore_trust_anchor
= plc
.ignore_trust_anchor
;
602 if (flags
& KC_VALIDITY_ADJUSTTIME
) {
603 free(oplc
.validity_adjusttime
);
604 oplc
.validity_adjusttime
=
605 plc
.validity_adjusttime
;
608 if (flags
& KC_TA_NAME
) {
610 oplc
.ta_name
= plc
.ta_name
;
612 if (flags
& KC_TA_SERIAL
) {
613 free(oplc
.ta_serial
);
614 oplc
.ta_serial
= plc
.ta_serial
;
618 * There are some combinations of attributes that are not valid.
620 * First, setting mapper-name (with optional mapper-directory) and
621 * mapper-pathname is mutually exclusive.
623 if ((mapper_name
!= NULL
&& mapper_pathname
!= NULL
) ||
624 (mapper_name
!= NULL
&& oplc
.mapper
.pathname
!= NULL
) ||
625 (mapper_pathname
!= NULL
&& oplc
.mapper
.mapname
!= NULL
) ||
626 /* Mapper directory can be set only if mapper name is set. */
627 (mapper_dir
!= NULL
&& mapper_pathname
!= NULL
) ||
628 (mapper_dir
!= NULL
&& mapper_name
== NULL
&&
629 oplc
.mapper
.mapname
== NULL
) ||
630 (mapper_dir
!= NULL
&& oplc
.mapper
.pathname
!= NULL
) ||
631 /* Options can be set only if mapper name or pathname is set. */
632 ((plc
.mapper
.options
!= NULL
|| oplc
.mapper
.options
!= NULL
) &&
633 (mapper_name
== NULL
&& oplc
.mapper
.mapname
== NULL
&&
634 mapper_pathname
== NULL
&& oplc
.mapper
.pathname
== NULL
))) {
635 (void) fprintf(stderr
,
636 gettext("Error in mapper input options\n"));
638 free(mapper_pathname
);
640 if (flags
& KC_MAPPER_OPTIONS
)
641 free(plc
.mapper
.options
);
645 if (mapper_name
!= NULL
)
646 plc
.mapper
.mapname
= mapper_name
;
647 if (mapper_pathname
!= NULL
)
648 plc
.mapper
.pathname
= mapper_pathname
;
649 if (mapper_dir
!= NULL
)
650 plc
.mapper
.dir
= mapper_dir
;
653 UPDATE_IF_DIFFERENT(oplc
.mapper
.mapname
, plc
.mapper
.mapname
);
654 UPDATE_IF_DIFFERENT(oplc
.mapper
.pathname
, plc
.mapper
.pathname
);
655 UPDATE_IF_DIFFERENT(oplc
.mapper
.dir
, plc
.mapper
.dir
);
657 if (flags
& KC_MAPPER_OPTIONS
) {
658 free(oplc
.mapper
.options
);
659 oplc
.mapper
.options
= plc
.mapper
.options
;
662 /* Update the OCSP policy */
663 if (ocsp_none_opt
== B_TRUE
) {
664 if (ocsp_set_attr
> 0) {
665 (void) fprintf(stderr
,
666 gettext("Can not set ocsp-none=true and other "
667 "OCSP attributes at the same time.\n"));
673 * If the original policy does not have OCSP checking,
674 * then we do not need to do anything. If the original
675 * policy has the OCSP checking, then we need to release the
676 * space of OCSP attributes and turn the OCSP checking off.
678 if (oplc
.revocation
& KMF_REVOCATION_METHOD_OCSP
) {
679 if (oplc
.VAL_OCSP_BASIC
.responderURI
) {
680 free(oplc
.VAL_OCSP_BASIC
.responderURI
);
681 oplc
.VAL_OCSP_BASIC
.responderURI
= NULL
;
684 if (oplc
.VAL_OCSP_BASIC
.proxy
) {
685 free(oplc
.VAL_OCSP_BASIC
.proxy
);
686 oplc
.VAL_OCSP_BASIC
.proxy
= NULL
;
689 if (oplc
.VAL_OCSP_BASIC
.response_lifetime
) {
690 free(oplc
.VAL_OCSP_BASIC
.response_lifetime
);
691 oplc
.VAL_OCSP_BASIC
.response_lifetime
= NULL
;
694 if (flags
& KC_OCSP_RESP_CERT_NAME
) {
695 free(oplc
.VAL_OCSP_RESP_CERT
.name
);
696 oplc
.VAL_OCSP_RESP_CERT
.name
= NULL
;
699 if (flags
& KC_OCSP_RESP_CERT_SERIAL
) {
700 free(oplc
.VAL_OCSP_RESP_CERT
.serial
);
701 oplc
.VAL_OCSP_RESP_CERT
.serial
= NULL
;
704 /* Turn off the OCSP checking */
705 oplc
.revocation
&= ~KMF_REVOCATION_METHOD_OCSP
;
710 * If the "ocsp-none" option is not set or is set to false,
711 * then we only need to do the modification if there is at
712 * least one OCSP attribute is specified.
714 if (ocsp_set_attr
> 0) {
715 if (flags
& KC_OCSP_RESPONDER_URI
) {
716 free(oplc
.VAL_OCSP_RESPONDER_URI
);
717 oplc
.VAL_OCSP_RESPONDER_URI
=
718 plc
.VAL_OCSP_RESPONDER_URI
;
721 if (flags
& KC_OCSP_PROXY
) {
722 free(oplc
.VAL_OCSP_PROXY
);
723 oplc
.VAL_OCSP_PROXY
= plc
.VAL_OCSP_PROXY
;
726 if (flags
& KC_OCSP_URI_FROM_CERT
)
727 oplc
.VAL_OCSP_URI_FROM_CERT
=
728 plc
.VAL_OCSP_URI_FROM_CERT
;
730 if (flags
& KC_OCSP_RESP_LIFETIME
) {
731 free(oplc
.VAL_OCSP_RESP_LIFETIME
);
732 oplc
.VAL_OCSP_RESP_LIFETIME
=
733 plc
.VAL_OCSP_RESP_LIFETIME
;
736 if (flags
& KC_OCSP_IGNORE_RESP_SIGN
)
737 oplc
.VAL_OCSP_IGNORE_RESP_SIGN
=
738 plc
.VAL_OCSP_IGNORE_RESP_SIGN
;
740 if (flags
& KC_OCSP_RESP_CERT_NAME
) {
741 free(oplc
.VAL_OCSP_RESP_CERT_NAME
);
742 oplc
.VAL_OCSP_RESP_CERT_NAME
=
743 plc
.VAL_OCSP_RESP_CERT_NAME
;
746 if (flags
& KC_OCSP_RESP_CERT_SERIAL
) {
747 free(oplc
.VAL_OCSP_RESP_CERT_SERIAL
);
748 oplc
.VAL_OCSP_RESP_CERT_SERIAL
=
749 plc
.VAL_OCSP_RESP_CERT_SERIAL
;
752 if (oplc
.VAL_OCSP_RESP_CERT_NAME
!= NULL
&&
753 oplc
.VAL_OCSP_RESP_CERT_SERIAL
!= NULL
)
754 oplc
.VAL_OCSP
.has_resp_cert
= B_TRUE
;
756 oplc
.VAL_OCSP
.has_resp_cert
= B_FALSE
;
758 /* Turn on the OCSP checking */
759 oplc
.revocation
|= KMF_REVOCATION_METHOD_OCSP
;
763 /* Update the CRL policy */
764 if (crl_none_opt
== B_TRUE
) {
765 if (crl_set_attr
> 0) {
766 (void) fprintf(stderr
,
767 gettext("Can not set crl-none=true and other CRL "
768 "attributes at the same time.\n"));
774 * If the original policy does not have CRL checking,
775 * then we do not need to do anything. If the original
776 * policy has the CRL checking, then we need to release the
777 * space of CRL attributes and turn the CRL checking off.
779 if (oplc
.revocation
& KMF_REVOCATION_METHOD_CRL
) {
780 if (oplc
.VAL_CRL_BASEFILENAME
) {
781 free(oplc
.VAL_CRL_BASEFILENAME
);
782 oplc
.VAL_CRL_BASEFILENAME
= NULL
;
785 if (oplc
.VAL_CRL_DIRECTORY
) {
786 free(oplc
.VAL_CRL_DIRECTORY
);
787 oplc
.VAL_CRL_DIRECTORY
= NULL
;
790 if (oplc
.VAL_CRL_PROXY
) {
791 free(oplc
.VAL_CRL_PROXY
);
792 oplc
.VAL_CRL_PROXY
= NULL
;
795 /* Turn off the CRL checking */
796 oplc
.revocation
&= ~KMF_REVOCATION_METHOD_CRL
;
800 * If the "ocsp-none" option is not set or is set to false,
801 * then we only need to do the modification if there is at
802 * least one CRL attribute is specified.
804 if (crl_set_attr
> 0) {
805 if (flags
& KC_CRL_BASEFILENAME
) {
806 free(oplc
.VAL_CRL_BASEFILENAME
);
807 oplc
.VAL_CRL_BASEFILENAME
=
808 plc
.VAL_CRL_BASEFILENAME
;
811 if (flags
& KC_CRL_DIRECTORY
) {
812 free(oplc
.VAL_CRL_DIRECTORY
);
813 oplc
.VAL_CRL_DIRECTORY
= plc
.VAL_CRL_DIRECTORY
;
816 if (flags
& KC_CRL_GET_URI
) {
817 oplc
.VAL_CRL_GET_URI
= plc
.VAL_CRL_GET_URI
;
820 if (flags
& KC_CRL_PROXY
) {
821 free(oplc
.VAL_CRL_PROXY
);
822 oplc
.VAL_CRL_PROXY
= plc
.VAL_CRL_PROXY
;
825 if (flags
& KC_CRL_IGNORE_SIGN
) {
826 oplc
.VAL_CRL_IGNORE_SIGN
=
827 plc
.VAL_CRL_IGNORE_SIGN
;
830 if (flags
& KC_CRL_IGNORE_DATE
) {
831 oplc
.VAL_CRL_IGNORE_DATE
=
832 plc
.VAL_CRL_IGNORE_DATE
;
835 /* Turn on the CRL checking */
836 oplc
.revocation
|= KMF_REVOCATION_METHOD_CRL
;
840 /* Update the Key Usage */
841 if (ku_none_opt
== B_TRUE
) {
842 if (flags
& KC_KEYUSAGE
) {
843 (void) fprintf(stderr
,
844 gettext("Can not set keyusage-none=true and "
845 "modify the keyusage value at the same time.\n"));
853 * If the "keyusage-none" option is not set or is set to
854 * false, then we only need to do the modification if
855 * the keyusage value is specified.
857 if (flags
& KC_KEYUSAGE
)
858 oplc
.ku_bits
= plc
.ku_bits
;
862 /* Update the Extended Key Usage */
863 if (eku_none_opt
== B_TRUE
) {
864 if (flags
& KC_EKUS
) {
865 (void) fprintf(stderr
,
866 gettext("Can not set eku-none=true and modify "
867 "EKU values at the same time.\n"));
872 /* Release current EKU list (if any) */
873 if (oplc
.eku_set
.eku_count
> 0) {
874 kmf_free_eku_policy(&oplc
.eku_set
);
875 oplc
.eku_set
.eku_count
= 0;
876 oplc
.eku_set
.ekulist
= NULL
;
880 * If the "eku-none" option is not set or is set to false,
881 * then we only need to do the modification if either
882 * "ekuname" or "ekuoids" is specified.
884 if (flags
& KC_EKUS
) {
885 /* Release current EKU list (if any) */
886 kmf_free_eku_policy(&oplc
.eku_set
);
887 oplc
.eku_set
= plc
.eku_set
;
891 /* Do a sanity check on the modified policy */
892 ret
= kmf_verify_policy(&oplc
);
894 print_sanity_error(ret
);
895 rv
= KC_ERR_VERIFY_POLICY
;
899 /* The modify operation is a delete followed by an add */
900 ret
= kmf_delete_policy_from_db(oplc
.name
, filename
);
902 rv
= KC_ERR_DELETE_POLICY
;
907 * Now add the modified policy back to the DB.
909 ret
= kmf_add_policy_to_db(&oplc
, filename
, B_FALSE
);
911 (void) fprintf(stderr
,
912 gettext("Error adding policy to database: 0x%04x\n"), ret
);
913 rv
= KC_ERR_ADD_POLICY
;
920 kmf_free_policy_record(&oplc
);
926 kc_modify_plugin(int argc
, char *argv
[])
930 extern int optind_av
;
931 extern char *optarg_av
;
932 char *keystore_name
= NULL
;
934 boolean_t modify_plugin
= B_FALSE
;
935 boolean_t has_option_arg
= B_FALSE
;
936 conf_entry_t
*entry
= NULL
;
938 FILE *pfile_tmp
= NULL
;
939 char tmpfile_name
[MAXPATHLEN
];
940 char buffer
[MAXPATHLEN
];
941 char buffer2
[MAXPATHLEN
];
943 while ((opt
= getopt_av(argc
, argv
, "p(plugin)k:(keystore)o:(option)"))
948 (void) fprintf(stderr
,
949 gettext("duplicate plugin input.\n"));
952 modify_plugin
= B_TRUE
;
956 if (keystore_name
!= NULL
)
959 keystore_name
= get_string(optarg_av
, &rv
);
960 if (keystore_name
== NULL
) {
961 (void) fprintf(stderr
, gettext(
962 "Error keystore input.\n"));
968 if (has_option_arg
) {
969 (void) fprintf(stderr
,
970 gettext("duplicate option input.\n"));
973 has_option_arg
= B_TRUE
;
974 option
= get_string(optarg_av
, NULL
);
978 (void) fprintf(stderr
,
979 gettext("Error input option.\n"));
988 /* No additional args allowed. */
991 (void) fprintf(stderr
,
992 gettext("Error input option\n"));
997 if (keystore_name
== NULL
|| has_option_arg
== B_FALSE
) {
998 (void) fprintf(stderr
,
999 gettext("Error input option\n"));
1004 if (strcasecmp(keystore_name
, "nss") == 0 ||
1005 strcasecmp(keystore_name
, "pkcs11") == 0 ||
1006 strcasecmp(keystore_name
, "file") == 0) {
1007 (void) fprintf(stderr
,
1008 gettext("Can not modify the built-in keystore %s\n"),
1014 entry
= get_keystore_entry(keystore_name
);
1015 if (entry
== NULL
) {
1016 (void) fprintf(stderr
, gettext("%s does not exist.\n"),
1022 if ((entry
->option
== NULL
&& option
== NULL
) ||
1023 (entry
->option
!= NULL
&& option
!= NULL
&&
1024 strcmp(entry
->option
, option
) == 0)) {
1025 (void) fprintf(stderr
, gettext("No change - "
1026 "the new option is same as the old option.\n"));
1031 if ((pfile
= fopen(_PATH_KMF_CONF
, "r+")) == NULL
) {
1033 (void) fprintf(stderr
,
1034 gettext("failed to update the configuration - %s\n"),
1040 if (lockf(fileno(pfile
), F_TLOCK
, 0) == -1) {
1042 (void) fprintf(stderr
,
1043 gettext("failed to lock the configuration - %s\n"),
1045 rv
= KC_ERR_MODIFY_PLUGIN
;
1050 * Create a temporary file in the /etc/crypto directory.
1052 (void) strlcpy(tmpfile_name
, CONF_TEMPFILE
, sizeof (tmpfile_name
));
1053 if (mkstemp(tmpfile_name
) == -1) {
1055 (void) fprintf(stderr
,
1056 gettext("failed to create a temporary file - %s\n"),
1058 rv
= KC_ERR_MODIFY_PLUGIN
;
1062 if ((pfile_tmp
= fopen(tmpfile_name
, "w")) == NULL
) {
1064 (void) fprintf(stderr
,
1065 gettext("failed to open %s - %s\n"),
1066 tmpfile_name
, strerror(err
));
1067 rv
= KC_ERR_MODIFY_PLUGIN
;
1072 * Loop thru the config file and update the entry.
1074 while (fgets(buffer
, MAXPATHLEN
, pfile
) != NULL
) {
1078 if (buffer
[0] == '#') {
1079 if (fputs(buffer
, pfile_tmp
) == EOF
) {
1080 rv
= KC_ERR_MODIFY_PLUGIN
;
1088 * make a copy of the original buffer to buffer2. Also get
1089 * rid of the trailing '\n' from buffer2.
1091 (void) strlcpy(buffer2
, buffer
, MAXPATHLEN
);
1092 len
= strlen(buffer2
);
1093 if (buffer2
[len
-1] == '\n') {
1096 buffer2
[len
] = '\0';
1098 if ((name
= strtok(buffer2
, SEP_COLON
)) == NULL
) {
1099 rv
= KC_ERR_UNINSTALL
;
1103 if (strcmp(name
, keystore_name
) == 0) {
1104 /* found the entry */
1106 (void) snprintf(buffer
, MAXPATHLEN
,
1107 "%s:%s%s\n", keystore_name
,
1108 CONF_MODULEPATH
, entry
->modulepath
);
1110 (void) snprintf(buffer
, MAXPATHLEN
,
1111 "%s:%s%s;%s%s\n", keystore_name
,
1112 CONF_MODULEPATH
, entry
->modulepath
,
1113 CONF_OPTION
, option
);
1115 if (fputs(buffer
, pfile_tmp
) == EOF
) {
1117 (void) fprintf(stderr
, gettext(
1118 "failed to write to %s: %s\n"),
1119 tmpfile_name
, strerror(err
));
1120 rv
= KC_ERR_MODIFY_PLUGIN
;
1125 if (fputs(buffer
, pfile_tmp
) == EOF
) {
1126 rv
= KC_ERR_UNINSTALL
;
1132 if (rename(tmpfile_name
, _PATH_KMF_CONF
) == -1) {
1134 (void) fprintf(stderr
, gettext(
1135 "failed to update the configuration - %s"), strerror(err
));
1136 rv
= KC_ERR_MODIFY_PLUGIN
;
1140 if (chmod(_PATH_KMF_CONF
,
1141 S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IROTH
) == -1) {
1143 (void) fprintf(stderr
, gettext(
1144 "failed to update the configuration - %s\n"),
1146 rv
= KC_ERR_MODIFY_PLUGIN
;
1155 (void) fclose(pfile
);
1157 if (rv
!= KC_OK
&& pfile_tmp
!= NULL
)
1158 (void) unlink(tmpfile_name
);
1160 if (pfile_tmp
!= NULL
)
1161 (void) fclose(pfile_tmp
);
1168 kc_modify(int argc
, char *argv
[])
1171 strcmp(argv
[0], "modify") == 0 &&
1172 strcmp(argv
[1], "plugin") == 0) {
1173 return (kc_modify_plugin(argc
, argv
));
1175 return (kc_modify_policy(argc
, argv
));