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)) { \
74 kc_modify_policy(int argc
, char *argv
[])
80 extern char *optarg_av
;
81 char *filename
= NULL
;
82 char *mapper_name
= NULL
;
83 char *mapper_dir
= NULL
;
84 char *mapper_pathname
= NULL
;
86 boolean_t ocsp_none_opt
= B_FALSE
;
87 boolean_t crl_none_opt
= B_FALSE
;
88 boolean_t ku_none_opt
= B_FALSE
;
89 boolean_t eku_none_opt
= B_FALSE
;
90 int ocsp_set_attr
= 0;
92 KMF_POLICY_RECORD oplc
, plc
;
94 (void) memset(&plc
, 0, sizeof (KMF_POLICY_RECORD
));
95 (void) memset(&oplc
, 0, sizeof (KMF_POLICY_RECORD
));
97 while ((opt
= getopt_av(argc
, argv
,
101 "e:(ignore-unknown-eku)"
102 "a:(ignore-trust-anchor)"
103 "v:(validity-adjusttime)"
108 "r:(ocsp-use-cert-responder)"
109 "T:(ocsp-response-lifetime)"
110 "R:(ocsp-ignore-response-sign)"
111 "n:(ocsp-responder-cert-name)"
112 "A:(ocsp-responder-cert-serial)"
114 "c:(crl-basefilename)"
116 "g:(crl-get-crl-uri)"
118 "S:(crl-ignore-crl-sign)"
119 "D:(crl-ignore-crl-date)"
126 "M:(mapper-directory)"
127 "Q:(mapper-pathname)"
129 "Z:(eku-none)")) != EOF
) {
132 filename
= get_string(optarg_av
, &rv
);
133 if (filename
== NULL
) {
134 (void) fprintf(stderr
,
135 gettext("Error dbfile input.\n"));
139 plc
.name
= get_string(optarg_av
, &rv
);
140 if (plc
.name
== NULL
) {
141 (void) fprintf(stderr
,
142 gettext("Error policy name.\n"));
146 plc
.ignore_date
= get_boolean(optarg_av
);
147 if (plc
.ignore_date
== -1) {
148 (void) fprintf(stderr
,
149 gettext("Error boolean input.\n"));
152 flags
|= KC_IGNORE_DATE
;
156 plc
.ignore_unknown_ekus
=
157 get_boolean(optarg_av
);
158 if (plc
.ignore_unknown_ekus
== -1) {
159 (void) fprintf(stderr
,
160 gettext("Error boolean input.\n"));
163 flags
|= KC_IGNORE_UNKNOWN_EKUS
;
167 plc
.ignore_trust_anchor
=
168 get_boolean(optarg_av
);
169 if (plc
.ignore_trust_anchor
== -1) {
170 (void) fprintf(stderr
,
171 gettext("Error boolean input.\n"));
174 flags
|= KC_IGNORE_TRUST_ANCHOR
;
178 plc
.validity_adjusttime
=
179 get_string(optarg_av
, &rv
);
180 if (plc
.validity_adjusttime
== NULL
) {
181 (void) fprintf(stderr
,
182 gettext("Error time input.\n"));
185 /* for syntax checking */
187 plc
.validity_adjusttime
,
189 (void) fprintf(stderr
,
190 gettext("Error time "
194 flags
|= KC_VALIDITY_ADJUSTTIME
;
199 plc
.ta_name
= get_string(optarg_av
, &rv
);
200 if (plc
.ta_name
== NULL
) {
201 (void) fprintf(stderr
,
202 gettext("Error name input.\n"));
203 } else if (strcasecmp(plc
.ta_name
, "search")) {
205 /* for syntax checking */
206 if (kmf_dn_parser(plc
.ta_name
,
208 (void) fprintf(stderr
,
209 gettext("Error name "
221 plc
.ta_serial
= get_string(optarg_av
, &rv
);
222 if (plc
.ta_serial
== NULL
) {
223 (void) fprintf(stderr
,
224 gettext("Error serial input.\n"));
226 uchar_t
*bytes
= NULL
;
229 ret
= kmf_hexstr_to_bytes(
230 (uchar_t
*)plc
.ta_serial
,
232 if (ret
!= KMF_OK
|| bytes
== NULL
) {
233 (void) fprintf(stderr
,
234 gettext("serial number "
235 "must be specified as a "
244 flags
|= KC_TA_SERIAL
;
248 plc
.VAL_OCSP_RESPONDER_URI
=
249 get_string(optarg_av
, &rv
);
250 if (plc
.VAL_OCSP_RESPONDER_URI
== NULL
) {
251 (void) fprintf(stderr
,
252 gettext("Error responder "
255 flags
|= KC_OCSP_RESPONDER_URI
;
260 plc
.VAL_OCSP_PROXY
= get_string(optarg_av
, &rv
);
261 if (plc
.VAL_OCSP_PROXY
== NULL
) {
262 (void) fprintf(stderr
,
263 gettext("Error proxy input.\n"));
265 flags
|= KC_OCSP_PROXY
;
270 plc
.VAL_OCSP_URI_FROM_CERT
=
271 get_boolean(optarg_av
);
272 if (plc
.VAL_OCSP_URI_FROM_CERT
== -1) {
273 (void) fprintf(stderr
,
274 gettext("Error boolean input.\n"));
277 flags
|= KC_OCSP_URI_FROM_CERT
;
282 plc
.VAL_OCSP_RESP_LIFETIME
=
283 get_string(optarg_av
, &rv
);
284 if (plc
.VAL_OCSP_RESP_LIFETIME
== NULL
) {
285 (void) fprintf(stderr
,
286 gettext("Error time input.\n"));
289 /* for syntax checking */
291 plc
.VAL_OCSP_RESP_LIFETIME
,
293 (void) fprintf(stderr
,
294 gettext("Error time "
298 flags
|= KC_OCSP_RESP_LIFETIME
;
304 plc
.VAL_OCSP_IGNORE_RESP_SIGN
=
305 get_boolean(optarg_av
);
306 if (plc
.VAL_OCSP_IGNORE_RESP_SIGN
== -1) {
307 (void) fprintf(stderr
,
308 gettext("Error boolean input.\n"));
311 flags
|= KC_OCSP_IGNORE_RESP_SIGN
;
316 plc
.VAL_OCSP_RESP_CERT_NAME
=
317 get_string(optarg_av
, &rv
);
318 if (plc
.VAL_OCSP_RESP_CERT_NAME
== NULL
) {
319 (void) fprintf(stderr
,
320 gettext("Error name input.\n"));
322 KMF_X509_NAME respDN
;
323 /* for syntax checking */
325 plc
.VAL_OCSP_RESP_CERT_NAME
,
326 &respDN
) != KMF_OK
) {
327 (void) fprintf(stderr
,
328 gettext("Error name "
332 kmf_free_dn(&respDN
);
333 flags
|= KC_OCSP_RESP_CERT_NAME
;
339 plc
.VAL_OCSP_RESP_CERT_SERIAL
=
340 get_string(optarg_av
, &rv
);
341 if (plc
.VAL_OCSP_RESP_CERT_SERIAL
== NULL
) {
342 (void) fprintf(stderr
,
343 gettext("Error serial input.\n"));
345 uchar_t
*bytes
= NULL
;
348 ret
= kmf_hexstr_to_bytes((uchar_t
*)
349 plc
.VAL_OCSP_RESP_CERT_SERIAL
,
351 if (ret
!= KMF_OK
|| bytes
== NULL
) {
352 (void) fprintf(stderr
,
353 gettext("serial number "
354 "must be specified as a "
363 flags
|= KC_OCSP_RESP_CERT_SERIAL
;
368 ocsp_none_opt
= get_boolean(optarg_av
);
369 if (ocsp_none_opt
== -1) {
370 (void) fprintf(stderr
,
371 gettext("Error boolean input.\n"));
374 flags
|= KC_OCSP_NONE
;
378 plc
.VAL_CRL_BASEFILENAME
=
379 get_string(optarg_av
, &rv
);
380 if (plc
.VAL_CRL_BASEFILENAME
== NULL
) {
381 (void) fprintf(stderr
, gettext(
382 "Error basefilename input.\n"));
384 flags
|= KC_CRL_BASEFILENAME
;
389 plc
.VAL_CRL_DIRECTORY
=
390 get_string(optarg_av
, &rv
);
391 if (plc
.VAL_CRL_DIRECTORY
== NULL
) {
392 (void) fprintf(stderr
,
393 gettext("Error boolean input.\n"));
395 flags
|= KC_CRL_DIRECTORY
;
400 plc
.VAL_CRL_GET_URI
= get_boolean(optarg_av
);
401 if (plc
.VAL_CRL_GET_URI
== -1) {
402 (void) fprintf(stderr
,
403 gettext("Error boolean input.\n"));
406 flags
|= KC_CRL_GET_URI
;
411 plc
.VAL_CRL_PROXY
= get_string(optarg_av
, &rv
);
412 if (plc
.VAL_CRL_PROXY
== NULL
) {
413 (void) fprintf(stderr
,
414 gettext("Error proxy input.\n"));
416 flags
|= KC_CRL_PROXY
;
421 plc
.VAL_CRL_IGNORE_SIGN
=
422 get_boolean(optarg_av
);
423 if (plc
.VAL_CRL_IGNORE_SIGN
== -1) {
424 (void) fprintf(stderr
,
425 gettext("Error boolean input.\n"));
428 flags
|= KC_CRL_IGNORE_SIGN
;
433 plc
.VAL_CRL_IGNORE_DATE
=
434 get_boolean(optarg_av
);
435 if (plc
.VAL_CRL_IGNORE_DATE
== -1) {
436 (void) fprintf(stderr
,
437 gettext("Error boolean input.\n"));
440 flags
|= KC_CRL_IGNORE_DATE
;
445 crl_none_opt
= get_boolean(optarg_av
);
446 if (crl_none_opt
== -1) {
447 (void) fprintf(stderr
,
448 gettext("Error boolean input.\n"));
451 flags
|= KC_CRL_NONE
;
455 plc
.ku_bits
= parseKUlist(optarg_av
);
456 if (plc
.ku_bits
== 0) {
457 (void) fprintf(stderr
, gettext(
458 "Error keyusage input.\n"));
461 flags
|= KC_KEYUSAGE
;
465 ku_none_opt
= get_boolean(optarg_av
);
466 if (ku_none_opt
== -1) {
467 (void) fprintf(stderr
,
468 gettext("Error boolean input.\n"));
471 flags
|= KC_KEYUSAGE_NONE
;
475 if (parseEKUNames(optarg_av
, &plc
) != 0) {
476 (void) fprintf(stderr
,
477 gettext("Error EKU input.\n"));
484 if (parseEKUOIDs(optarg_av
, &plc
) != 0) {
485 (void) fprintf(stderr
,
486 gettext("Error EKU OID input.\n"));
493 eku_none_opt
= get_boolean(optarg_av
);
494 if (eku_none_opt
== -1) {
495 (void) fprintf(stderr
,
496 gettext("Error boolean input.\n"));
499 flags
|= KC_EKUS_NONE
;
503 mapper_name
= get_string(optarg_av
, &rv
);
504 if (mapper_name
== NULL
) {
505 (void) fprintf(stderr
,
506 gettext("Error mapper-name "
511 mapper_dir
= get_string(optarg_av
, &rv
);
512 if (mapper_dir
== NULL
) {
513 (void) fprintf(stderr
,
514 gettext("Error mapper-directory "
519 mapper_pathname
= get_string(optarg_av
, &rv
);
520 if (mapper_pathname
== NULL
) {
521 (void) fprintf(stderr
,
522 gettext("Error mapper-pathname "
527 plc
.mapper
.options
= get_string(optarg_av
, &rv
);
528 rv
= 0; /* its ok for this to be NULL */
529 flags
|= KC_MAPPER_OPTIONS
;
532 (void) fprintf(stderr
,
533 gettext("Error input option.\n"));
541 /* No additional args allowed. */
544 (void) fprintf(stderr
,
545 gettext("Error input option\n"));
550 if (filename
== NULL
) {
551 filename
= strdup(KMF_DEFAULT_POLICY_FILE
);
552 if (filename
== NULL
) {
559 * Must have a policy name. The policy name can not be default
560 * if using the default policy file.
562 if (plc
.name
== NULL
) {
563 (void) fprintf(stderr
,
564 gettext("You must specify a policy name.\n"));
567 } else if (strcmp(filename
, KMF_DEFAULT_POLICY_FILE
) == 0 &&
568 strcmp(plc
.name
, KMF_DEFAULT_POLICY_NAME
) == 0) {
569 (void) fprintf(stderr
,
570 gettext("Can not modify the default policy in the default "
576 /* Check the access permission of the policy DB */
577 if (access(filename
, W_OK
) < 0) {
579 (void) fprintf(stderr
,
580 gettext("Cannot access \"%s\" for modify - %s\n"),
581 filename
, strerror(err
));
586 /* Try to load the named policy from the DB */
587 ret
= kmf_get_policy(filename
, plc
.name
, &oplc
);
589 (void) fprintf(stderr
,
590 gettext("Error loading policy \"%s\" from %s\n"), filename
,
592 return (KC_ERR_FIND_POLICY
);
595 /* Update the general policy attributes. */
596 if (flags
& KC_IGNORE_DATE
)
597 oplc
.ignore_date
= plc
.ignore_date
;
599 if (flags
& KC_IGNORE_UNKNOWN_EKUS
)
600 oplc
.ignore_unknown_ekus
= plc
.ignore_unknown_ekus
;
602 if (flags
& KC_IGNORE_TRUST_ANCHOR
)
603 oplc
.ignore_trust_anchor
= plc
.ignore_trust_anchor
;
605 if (flags
& KC_VALIDITY_ADJUSTTIME
) {
606 if (oplc
.validity_adjusttime
)
607 free(oplc
.validity_adjusttime
);
608 oplc
.validity_adjusttime
=
609 plc
.validity_adjusttime
;
612 if (flags
& KC_TA_NAME
) {
615 oplc
.ta_name
= plc
.ta_name
;
617 if (flags
& KC_TA_SERIAL
) {
619 free(oplc
.ta_serial
);
620 oplc
.ta_serial
= plc
.ta_serial
;
624 * There are some combinations of attributes that are not valid.
626 * First, setting mapper-name (with optional mapper-directory) and
627 * mapper-pathname is mutually exclusive.
629 if ((mapper_name
!= NULL
&& mapper_pathname
!= NULL
) ||
630 (mapper_name
!= NULL
&& oplc
.mapper
.pathname
!= NULL
) ||
631 (mapper_pathname
!= NULL
&& oplc
.mapper
.mapname
!= NULL
) ||
632 /* Mapper directory can be set only if mapper name is set. */
633 (mapper_dir
!= NULL
&& mapper_pathname
!= NULL
) ||
634 (mapper_dir
!= NULL
&& mapper_name
== NULL
&&
635 oplc
.mapper
.mapname
== NULL
) ||
636 (mapper_dir
!= NULL
&& oplc
.mapper
.pathname
!= NULL
) ||
637 /* Options can be set only if mapper name or pathname is set. */
638 ((plc
.mapper
.options
!= NULL
|| oplc
.mapper
.options
!= NULL
) &&
639 (mapper_name
== NULL
&& oplc
.mapper
.mapname
== NULL
&&
640 mapper_pathname
== NULL
&& oplc
.mapper
.pathname
== NULL
))) {
641 (void) fprintf(stderr
,
642 gettext("Error in mapper input options\n"));
643 if (mapper_name
!= NULL
)
645 if (mapper_pathname
!= NULL
)
646 free(mapper_pathname
);
647 if (mapper_dir
!= NULL
)
649 if (flags
& KC_MAPPER_OPTIONS
&& plc
.mapper
.options
!= NULL
)
650 free(plc
.mapper
.options
);
654 if (mapper_name
!= NULL
)
655 plc
.mapper
.mapname
= mapper_name
;
656 if (mapper_pathname
!= NULL
)
657 plc
.mapper
.pathname
= mapper_pathname
;
658 if (mapper_dir
!= NULL
)
659 plc
.mapper
.dir
= mapper_dir
;
662 UPDATE_IF_DIFFERENT(oplc
.mapper
.mapname
, plc
.mapper
.mapname
);
663 UPDATE_IF_DIFFERENT(oplc
.mapper
.pathname
, plc
.mapper
.pathname
);
664 UPDATE_IF_DIFFERENT(oplc
.mapper
.dir
, plc
.mapper
.dir
);
666 if (flags
& KC_MAPPER_OPTIONS
) {
667 if (oplc
.mapper
.options
!= NULL
)
668 free(oplc
.mapper
.options
);
669 oplc
.mapper
.options
= plc
.mapper
.options
;
672 /* Update the OCSP policy */
673 if (ocsp_none_opt
== B_TRUE
) {
674 if (ocsp_set_attr
> 0) {
675 (void) fprintf(stderr
,
676 gettext("Can not set ocsp-none=true and other "
677 "OCSP attributes at the same time.\n"));
683 * If the original policy does not have OCSP checking,
684 * then we do not need to do anything. If the original
685 * policy has the OCSP checking, then we need to release the
686 * space of OCSP attributes and turn the OCSP checking off.
688 if (oplc
.revocation
& KMF_REVOCATION_METHOD_OCSP
) {
689 if (oplc
.VAL_OCSP_BASIC
.responderURI
) {
690 free(oplc
.VAL_OCSP_BASIC
.responderURI
);
691 oplc
.VAL_OCSP_BASIC
.responderURI
= NULL
;
694 if (oplc
.VAL_OCSP_BASIC
.proxy
) {
695 free(oplc
.VAL_OCSP_BASIC
.proxy
);
696 oplc
.VAL_OCSP_BASIC
.proxy
= NULL
;
699 if (oplc
.VAL_OCSP_BASIC
.response_lifetime
) {
700 free(oplc
.VAL_OCSP_BASIC
.response_lifetime
);
701 oplc
.VAL_OCSP_BASIC
.response_lifetime
= NULL
;
704 if (flags
& KC_OCSP_RESP_CERT_NAME
) {
705 free(oplc
.VAL_OCSP_RESP_CERT
.name
);
706 oplc
.VAL_OCSP_RESP_CERT
.name
= NULL
;
709 if (flags
& KC_OCSP_RESP_CERT_SERIAL
) {
710 free(oplc
.VAL_OCSP_RESP_CERT
.serial
);
711 oplc
.VAL_OCSP_RESP_CERT
.serial
= NULL
;
714 /* Turn off the OCSP checking */
715 oplc
.revocation
&= ~KMF_REVOCATION_METHOD_OCSP
;
720 * If the "ocsp-none" option is not set or is set to false,
721 * then we only need to do the modification if there is at
722 * least one OCSP attribute is specified.
724 if (ocsp_set_attr
> 0) {
725 if (flags
& KC_OCSP_RESPONDER_URI
) {
726 if (oplc
.VAL_OCSP_RESPONDER_URI
)
727 free(oplc
.VAL_OCSP_RESPONDER_URI
);
728 oplc
.VAL_OCSP_RESPONDER_URI
=
729 plc
.VAL_OCSP_RESPONDER_URI
;
732 if (flags
& KC_OCSP_PROXY
) {
733 if (oplc
.VAL_OCSP_PROXY
)
734 free(oplc
.VAL_OCSP_PROXY
);
735 oplc
.VAL_OCSP_PROXY
= plc
.VAL_OCSP_PROXY
;
738 if (flags
& KC_OCSP_URI_FROM_CERT
)
739 oplc
.VAL_OCSP_URI_FROM_CERT
=
740 plc
.VAL_OCSP_URI_FROM_CERT
;
742 if (flags
& KC_OCSP_RESP_LIFETIME
) {
743 if (oplc
.VAL_OCSP_RESP_LIFETIME
)
744 free(oplc
.VAL_OCSP_RESP_LIFETIME
);
745 oplc
.VAL_OCSP_RESP_LIFETIME
=
746 plc
.VAL_OCSP_RESP_LIFETIME
;
749 if (flags
& KC_OCSP_IGNORE_RESP_SIGN
)
750 oplc
.VAL_OCSP_IGNORE_RESP_SIGN
=
751 plc
.VAL_OCSP_IGNORE_RESP_SIGN
;
753 if (flags
& KC_OCSP_RESP_CERT_NAME
) {
754 if (oplc
.VAL_OCSP_RESP_CERT_NAME
)
755 free(oplc
.VAL_OCSP_RESP_CERT_NAME
);
756 oplc
.VAL_OCSP_RESP_CERT_NAME
=
757 plc
.VAL_OCSP_RESP_CERT_NAME
;
760 if (flags
& KC_OCSP_RESP_CERT_SERIAL
) {
761 if (oplc
.VAL_OCSP_RESP_CERT_SERIAL
)
762 free(oplc
.VAL_OCSP_RESP_CERT_SERIAL
);
763 oplc
.VAL_OCSP_RESP_CERT_SERIAL
=
764 plc
.VAL_OCSP_RESP_CERT_SERIAL
;
767 if (oplc
.VAL_OCSP_RESP_CERT_NAME
!= NULL
&&
768 oplc
.VAL_OCSP_RESP_CERT_SERIAL
!= NULL
)
769 oplc
.VAL_OCSP
.has_resp_cert
= B_TRUE
;
771 oplc
.VAL_OCSP
.has_resp_cert
= B_FALSE
;
773 /* Turn on the OCSP checking */
774 oplc
.revocation
|= KMF_REVOCATION_METHOD_OCSP
;
778 /* Update the CRL policy */
779 if (crl_none_opt
== B_TRUE
) {
780 if (crl_set_attr
> 0) {
781 (void) fprintf(stderr
,
782 gettext("Can not set crl-none=true and other CRL "
783 "attributes at the same time.\n"));
789 * If the original policy does not have CRL checking,
790 * then we do not need to do anything. If the original
791 * policy has the CRL checking, then we need to release the
792 * space of CRL attributes and turn the CRL checking off.
794 if (oplc
.revocation
& KMF_REVOCATION_METHOD_CRL
) {
795 if (oplc
.VAL_CRL_BASEFILENAME
) {
796 free(oplc
.VAL_CRL_BASEFILENAME
);
797 oplc
.VAL_CRL_BASEFILENAME
= NULL
;
800 if (oplc
.VAL_CRL_DIRECTORY
) {
801 free(oplc
.VAL_CRL_DIRECTORY
);
802 oplc
.VAL_CRL_DIRECTORY
= NULL
;
805 if (oplc
.VAL_CRL_PROXY
) {
806 free(oplc
.VAL_CRL_PROXY
);
807 oplc
.VAL_CRL_PROXY
= NULL
;
810 /* Turn off the CRL checking */
811 oplc
.revocation
&= ~KMF_REVOCATION_METHOD_CRL
;
815 * If the "ocsp-none" option is not set or is set to false,
816 * then we only need to do the modification if there is at
817 * least one CRL attribute is specified.
819 if (crl_set_attr
> 0) {
820 if (flags
& KC_CRL_BASEFILENAME
) {
821 if (oplc
.VAL_CRL_BASEFILENAME
)
822 free(oplc
.VAL_CRL_BASEFILENAME
);
823 oplc
.VAL_CRL_BASEFILENAME
=
824 plc
.VAL_CRL_BASEFILENAME
;
827 if (flags
& KC_CRL_DIRECTORY
) {
828 if (oplc
.VAL_CRL_DIRECTORY
)
829 free(oplc
.VAL_CRL_DIRECTORY
);
830 oplc
.VAL_CRL_DIRECTORY
= plc
.VAL_CRL_DIRECTORY
;
833 if (flags
& KC_CRL_GET_URI
) {
834 oplc
.VAL_CRL_GET_URI
= plc
.VAL_CRL_GET_URI
;
837 if (flags
& KC_CRL_PROXY
) {
838 if (oplc
.VAL_CRL_PROXY
)
839 free(oplc
.VAL_CRL_PROXY
);
840 oplc
.VAL_CRL_PROXY
= plc
.VAL_CRL_PROXY
;
843 if (flags
& KC_CRL_IGNORE_SIGN
) {
844 oplc
.VAL_CRL_IGNORE_SIGN
=
845 plc
.VAL_CRL_IGNORE_SIGN
;
848 if (flags
& KC_CRL_IGNORE_DATE
) {
849 oplc
.VAL_CRL_IGNORE_DATE
=
850 plc
.VAL_CRL_IGNORE_DATE
;
853 /* Turn on the CRL checking */
854 oplc
.revocation
|= KMF_REVOCATION_METHOD_CRL
;
858 /* Update the Key Usage */
859 if (ku_none_opt
== B_TRUE
) {
860 if (flags
& KC_KEYUSAGE
) {
861 (void) fprintf(stderr
,
862 gettext("Can not set keyusage-none=true and "
863 "modify the keyusage value at the same time.\n"));
871 * If the "keyusage-none" option is not set or is set to
872 * false, then we only need to do the modification if
873 * the keyusage value is specified.
875 if (flags
& KC_KEYUSAGE
)
876 oplc
.ku_bits
= plc
.ku_bits
;
880 /* Update the Extended Key Usage */
881 if (eku_none_opt
== B_TRUE
) {
882 if (flags
& KC_EKUS
) {
883 (void) fprintf(stderr
,
884 gettext("Can not set eku-none=true and modify "
885 "EKU values at the same time.\n"));
890 /* Release current EKU list (if any) */
891 if (oplc
.eku_set
.eku_count
> 0) {
892 kmf_free_eku_policy(&oplc
.eku_set
);
893 oplc
.eku_set
.eku_count
= 0;
894 oplc
.eku_set
.ekulist
= NULL
;
898 * If the "eku-none" option is not set or is set to false,
899 * then we only need to do the modification if either
900 * "ekuname" or "ekuoids" is specified.
902 if (flags
& KC_EKUS
) {
903 /* Release current EKU list (if any) */
904 kmf_free_eku_policy(&oplc
.eku_set
);
905 oplc
.eku_set
= plc
.eku_set
;
909 /* Do a sanity check on the modified policy */
910 ret
= kmf_verify_policy(&oplc
);
912 print_sanity_error(ret
);
913 rv
= KC_ERR_VERIFY_POLICY
;
917 /* The modify operation is a delete followed by an add */
918 ret
= kmf_delete_policy_from_db(oplc
.name
, filename
);
920 rv
= KC_ERR_DELETE_POLICY
;
925 * Now add the modified policy back to the DB.
927 ret
= kmf_add_policy_to_db(&oplc
, filename
, B_FALSE
);
929 (void) fprintf(stderr
,
930 gettext("Error adding policy to database: 0x%04x\n"), ret
);
931 rv
= KC_ERR_ADD_POLICY
;
936 if (filename
!= NULL
)
939 kmf_free_policy_record(&oplc
);
945 kc_modify_plugin(int argc
, char *argv
[])
949 extern int optind_av
;
950 extern char *optarg_av
;
951 char *keystore_name
= NULL
;
953 boolean_t modify_plugin
= B_FALSE
;
954 boolean_t has_option_arg
= B_FALSE
;
955 conf_entry_t
*entry
= NULL
;
957 FILE *pfile_tmp
= NULL
;
958 char tmpfile_name
[MAXPATHLEN
];
959 char buffer
[MAXPATHLEN
];
960 char buffer2
[MAXPATHLEN
];
962 while ((opt
= getopt_av(argc
, argv
, "p(plugin)k:(keystore)o:(option)"))
967 (void) fprintf(stderr
,
968 gettext("duplicate plugin input.\n"));
971 modify_plugin
= B_TRUE
;
975 if (keystore_name
!= NULL
)
978 keystore_name
= get_string(optarg_av
, &rv
);
979 if (keystore_name
== NULL
) {
980 (void) fprintf(stderr
, gettext(
981 "Error keystore input.\n"));
987 if (has_option_arg
) {
988 (void) fprintf(stderr
,
989 gettext("duplicate option input.\n"));
992 has_option_arg
= B_TRUE
;
993 option
= get_string(optarg_av
, NULL
);
997 (void) fprintf(stderr
,
998 gettext("Error input option.\n"));
1007 /* No additional args allowed. */
1010 (void) fprintf(stderr
,
1011 gettext("Error input option\n"));
1016 if (keystore_name
== NULL
|| has_option_arg
== B_FALSE
) {
1017 (void) fprintf(stderr
,
1018 gettext("Error input option\n"));
1023 if (strcasecmp(keystore_name
, "nss") == 0 ||
1024 strcasecmp(keystore_name
, "pkcs11") == 0 ||
1025 strcasecmp(keystore_name
, "file") == 0) {
1026 (void) fprintf(stderr
,
1027 gettext("Can not modify the built-in keystore %s\n"),
1033 entry
= get_keystore_entry(keystore_name
);
1034 if (entry
== NULL
) {
1035 (void) fprintf(stderr
, gettext("%s does not exist.\n"),
1041 if ((entry
->option
== NULL
&& option
== NULL
) ||
1042 (entry
->option
!= NULL
&& option
!= NULL
&&
1043 strcmp(entry
->option
, option
) == 0)) {
1044 (void) fprintf(stderr
, gettext("No change - "
1045 "the new option is same as the old option.\n"));
1050 if ((pfile
= fopen(_PATH_KMF_CONF
, "r+")) == NULL
) {
1052 (void) fprintf(stderr
,
1053 gettext("failed to update the configuration - %s\n"),
1059 if (lockf(fileno(pfile
), F_TLOCK
, 0) == -1) {
1061 (void) fprintf(stderr
,
1062 gettext("failed to lock the configuration - %s\n"),
1064 rv
= KC_ERR_MODIFY_PLUGIN
;
1069 * Create a temporary file in the /etc/crypto directory.
1071 (void) strlcpy(tmpfile_name
, CONF_TEMPFILE
, sizeof (tmpfile_name
));
1072 if (mkstemp(tmpfile_name
) == -1) {
1074 (void) fprintf(stderr
,
1075 gettext("failed to create a temporary file - %s\n"),
1077 rv
= KC_ERR_MODIFY_PLUGIN
;
1081 if ((pfile_tmp
= fopen(tmpfile_name
, "w")) == NULL
) {
1083 (void) fprintf(stderr
,
1084 gettext("failed to open %s - %s\n"),
1085 tmpfile_name
, strerror(err
));
1086 rv
= KC_ERR_MODIFY_PLUGIN
;
1091 * Loop thru the config file and update the entry.
1093 while (fgets(buffer
, MAXPATHLEN
, pfile
) != NULL
) {
1097 if (buffer
[0] == '#') {
1098 if (fputs(buffer
, pfile_tmp
) == EOF
) {
1099 rv
= KC_ERR_MODIFY_PLUGIN
;
1107 * make a copy of the original buffer to buffer2. Also get
1108 * rid of the trailing '\n' from buffer2.
1110 (void) strlcpy(buffer2
, buffer
, MAXPATHLEN
);
1111 len
= strlen(buffer2
);
1112 if (buffer2
[len
-1] == '\n') {
1115 buffer2
[len
] = '\0';
1117 if ((name
= strtok(buffer2
, SEP_COLON
)) == NULL
) {
1118 rv
= KC_ERR_UNINSTALL
;
1122 if (strcmp(name
, keystore_name
) == 0) {
1123 /* found the entry */
1125 (void) snprintf(buffer
, MAXPATHLEN
,
1126 "%s:%s%s\n", keystore_name
,
1127 CONF_MODULEPATH
, entry
->modulepath
);
1129 (void) snprintf(buffer
, MAXPATHLEN
,
1130 "%s:%s%s;%s%s\n", keystore_name
,
1131 CONF_MODULEPATH
, entry
->modulepath
,
1132 CONF_OPTION
, option
);
1134 if (fputs(buffer
, pfile_tmp
) == EOF
) {
1136 (void) fprintf(stderr
, gettext(
1137 "failed to write to %s: %s\n"),
1138 tmpfile_name
, strerror(err
));
1139 rv
= KC_ERR_MODIFY_PLUGIN
;
1144 if (fputs(buffer
, pfile_tmp
) == EOF
) {
1145 rv
= KC_ERR_UNINSTALL
;
1151 if (rename(tmpfile_name
, _PATH_KMF_CONF
) == -1) {
1153 (void) fprintf(stderr
, gettext(
1154 "failed to update the configuration - %s"), strerror(err
));
1155 rv
= KC_ERR_MODIFY_PLUGIN
;
1159 if (chmod(_PATH_KMF_CONF
,
1160 S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IROTH
) == -1) {
1162 (void) fprintf(stderr
, gettext(
1163 "failed to update the configuration - %s\n"),
1165 rv
= KC_ERR_MODIFY_PLUGIN
;
1174 (void) fclose(pfile
);
1176 if (rv
!= KC_OK
&& pfile_tmp
!= NULL
)
1177 (void) unlink(tmpfile_name
);
1179 if (pfile_tmp
!= NULL
)
1180 (void) fclose(pfile_tmp
);
1187 kc_modify(int argc
, char *argv
[])
1190 strcmp(argv
[0], "modify") == 0 &&
1191 strcmp(argv
[1], "plugin") == 0) {
1192 return (kc_modify_plugin(argc
, argv
));
1194 return (kc_modify_policy(argc
, argv
));