17934SMark.Phalan@Sun.COM /*
27934SMark.Phalan@Sun.COM * COPYRIGHT (C) 2007
37934SMark.Phalan@Sun.COM * THE REGENTS OF THE UNIVERSITY OF MICHIGAN
47934SMark.Phalan@Sun.COM * ALL RIGHTS RESERVED
57934SMark.Phalan@Sun.COM *
67934SMark.Phalan@Sun.COM * Permission is granted to use, copy, create derivative works
77934SMark.Phalan@Sun.COM * and redistribute this software and such derivative works
87934SMark.Phalan@Sun.COM * for any purpose, so long as the name of The University of
97934SMark.Phalan@Sun.COM * Michigan is not used in any advertising or publicity
107934SMark.Phalan@Sun.COM * pertaining to the use of distribution of this software
117934SMark.Phalan@Sun.COM * without specific, written prior authorization. If the
127934SMark.Phalan@Sun.COM * above copyright notice or any other identification of the
137934SMark.Phalan@Sun.COM * University of Michigan is included in any copy of any
147934SMark.Phalan@Sun.COM * portion of this software, then the disclaimer below must
157934SMark.Phalan@Sun.COM * also be included.
167934SMark.Phalan@Sun.COM *
177934SMark.Phalan@Sun.COM * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION
187934SMark.Phalan@Sun.COM * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY
197934SMark.Phalan@Sun.COM * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF
207934SMark.Phalan@Sun.COM * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
217934SMark.Phalan@Sun.COM * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF
227934SMark.Phalan@Sun.COM * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
237934SMark.Phalan@Sun.COM * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE
247934SMark.Phalan@Sun.COM * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR
257934SMark.Phalan@Sun.COM * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING
267934SMark.Phalan@Sun.COM * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN
277934SMark.Phalan@Sun.COM * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF
287934SMark.Phalan@Sun.COM * SUCH DAMAGES.
297934SMark.Phalan@Sun.COM */
307934SMark.Phalan@Sun.COM
3112941Swill.fiveash@oracle.com /*
3212941Swill.fiveash@oracle.com * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
3312941Swill.fiveash@oracle.com */
3412941Swill.fiveash@oracle.com
357934SMark.Phalan@Sun.COM #include <errno.h>
367934SMark.Phalan@Sun.COM #include <string.h>
377934SMark.Phalan@Sun.COM #include <stdio.h>
387934SMark.Phalan@Sun.COM #include <stdlib.h>
397934SMark.Phalan@Sun.COM #include <dlfcn.h>
407934SMark.Phalan@Sun.COM #include <unistd.h>
417934SMark.Phalan@Sun.COM #include <dirent.h>
427934SMark.Phalan@Sun.COM
437934SMark.Phalan@Sun.COM #include <libintl.h>
447934SMark.Phalan@Sun.COM
457934SMark.Phalan@Sun.COM #include "pkinit.h"
467934SMark.Phalan@Sun.COM
477934SMark.Phalan@Sun.COM static void
free_list(char ** list)487934SMark.Phalan@Sun.COM free_list(char **list)
497934SMark.Phalan@Sun.COM {
507934SMark.Phalan@Sun.COM int i;
517934SMark.Phalan@Sun.COM
527934SMark.Phalan@Sun.COM if (list == NULL)
537934SMark.Phalan@Sun.COM return;
547934SMark.Phalan@Sun.COM
557934SMark.Phalan@Sun.COM for (i = 0; list[i] != NULL; i++)
567934SMark.Phalan@Sun.COM free(list[i]);
577934SMark.Phalan@Sun.COM free(list);
587934SMark.Phalan@Sun.COM }
597934SMark.Phalan@Sun.COM
607934SMark.Phalan@Sun.COM static krb5_error_code
copy_list(char *** dst,char ** src)617934SMark.Phalan@Sun.COM copy_list(char ***dst, char **src)
627934SMark.Phalan@Sun.COM {
637934SMark.Phalan@Sun.COM int i;
647934SMark.Phalan@Sun.COM char **newlist;
657934SMark.Phalan@Sun.COM
667934SMark.Phalan@Sun.COM if (dst == NULL)
677934SMark.Phalan@Sun.COM return EINVAL;
687934SMark.Phalan@Sun.COM *dst = NULL;
697934SMark.Phalan@Sun.COM
707934SMark.Phalan@Sun.COM if (src == NULL)
717934SMark.Phalan@Sun.COM return 0;
727934SMark.Phalan@Sun.COM
737934SMark.Phalan@Sun.COM for (i = 0; src[i] != NULL; i++);
747934SMark.Phalan@Sun.COM
757934SMark.Phalan@Sun.COM newlist = calloc(1, (i + 1) * sizeof(*newlist));
767934SMark.Phalan@Sun.COM if (newlist == NULL)
777934SMark.Phalan@Sun.COM return ENOMEM;
787934SMark.Phalan@Sun.COM
797934SMark.Phalan@Sun.COM for (i = 0; src[i] != NULL; i++) {
807934SMark.Phalan@Sun.COM newlist[i] = strdup(src[i]);
817934SMark.Phalan@Sun.COM if (newlist[i] == NULL)
827934SMark.Phalan@Sun.COM goto cleanup;
837934SMark.Phalan@Sun.COM }
847934SMark.Phalan@Sun.COM newlist[i] = NULL;
857934SMark.Phalan@Sun.COM *dst = newlist;
867934SMark.Phalan@Sun.COM return 0;
877934SMark.Phalan@Sun.COM cleanup:
887934SMark.Phalan@Sun.COM free_list(newlist);
897934SMark.Phalan@Sun.COM return ENOMEM;
907934SMark.Phalan@Sun.COM }
917934SMark.Phalan@Sun.COM
927934SMark.Phalan@Sun.COM char *
idtype2string(int idtype)937934SMark.Phalan@Sun.COM idtype2string(int idtype)
947934SMark.Phalan@Sun.COM {
957934SMark.Phalan@Sun.COM /* Solaris Kerberos: Removed "break"s (lint) */
967934SMark.Phalan@Sun.COM switch(idtype) {
977934SMark.Phalan@Sun.COM case IDTYPE_FILE: return "FILE";
987934SMark.Phalan@Sun.COM case IDTYPE_DIR: return "DIR";
997934SMark.Phalan@Sun.COM case IDTYPE_PKCS11: return "PKCS11";
1007934SMark.Phalan@Sun.COM case IDTYPE_PKCS12: return "PKCS12";
1017934SMark.Phalan@Sun.COM case IDTYPE_ENVVAR: return "ENV";
1027934SMark.Phalan@Sun.COM default: return "INVALID";
1037934SMark.Phalan@Sun.COM }
1047934SMark.Phalan@Sun.COM }
1057934SMark.Phalan@Sun.COM
1067934SMark.Phalan@Sun.COM char *
catype2string(int catype)1077934SMark.Phalan@Sun.COM catype2string(int catype)
1087934SMark.Phalan@Sun.COM {
1097934SMark.Phalan@Sun.COM /* Solaris Kerberos: Removed "break"s (lint) */
1107934SMark.Phalan@Sun.COM switch(catype) {
1117934SMark.Phalan@Sun.COM case CATYPE_ANCHORS: return "ANCHORS";
1127934SMark.Phalan@Sun.COM case CATYPE_INTERMEDIATES: return "INTERMEDIATES";
1137934SMark.Phalan@Sun.COM case CATYPE_CRLS: return "CRLS";
1147934SMark.Phalan@Sun.COM default: return "INVALID";
1157934SMark.Phalan@Sun.COM }
1167934SMark.Phalan@Sun.COM }
1177934SMark.Phalan@Sun.COM
1187934SMark.Phalan@Sun.COM krb5_error_code
pkinit_init_identity_opts(pkinit_identity_opts ** idopts)1197934SMark.Phalan@Sun.COM pkinit_init_identity_opts(pkinit_identity_opts **idopts)
1207934SMark.Phalan@Sun.COM {
1217934SMark.Phalan@Sun.COM pkinit_identity_opts *opts = NULL;
1227934SMark.Phalan@Sun.COM
1237934SMark.Phalan@Sun.COM *idopts = NULL;
1247934SMark.Phalan@Sun.COM opts = (pkinit_identity_opts *) calloc(1, sizeof(pkinit_identity_opts));
1257934SMark.Phalan@Sun.COM if (opts == NULL)
1267934SMark.Phalan@Sun.COM return ENOMEM;
1277934SMark.Phalan@Sun.COM
1287934SMark.Phalan@Sun.COM opts->identity = NULL;
1297934SMark.Phalan@Sun.COM opts->anchors = NULL;
1307934SMark.Phalan@Sun.COM opts->intermediates = NULL;
1317934SMark.Phalan@Sun.COM opts->crls = NULL;
1327934SMark.Phalan@Sun.COM opts->ocsp = NULL;
1337934SMark.Phalan@Sun.COM opts->dn_mapping_file = NULL;
1347934SMark.Phalan@Sun.COM
1357934SMark.Phalan@Sun.COM opts->cert_filename = NULL;
1367934SMark.Phalan@Sun.COM opts->key_filename = NULL;
1377934SMark.Phalan@Sun.COM #ifndef WITHOUT_PKCS11
1387934SMark.Phalan@Sun.COM opts->p11_module_name = NULL;
1397934SMark.Phalan@Sun.COM opts->slotid = PK_NOSLOT;
1407934SMark.Phalan@Sun.COM opts->token_label = NULL;
1417934SMark.Phalan@Sun.COM opts->cert_id_string = NULL;
1427934SMark.Phalan@Sun.COM opts->cert_label = NULL;
14312941Swill.fiveash@oracle.com opts->PIN = NULL;
1447934SMark.Phalan@Sun.COM #endif
1457934SMark.Phalan@Sun.COM
1467934SMark.Phalan@Sun.COM *idopts = opts;
1477934SMark.Phalan@Sun.COM
1487934SMark.Phalan@Sun.COM return 0;
1497934SMark.Phalan@Sun.COM }
1507934SMark.Phalan@Sun.COM
1517934SMark.Phalan@Sun.COM krb5_error_code
pkinit_dup_identity_opts(pkinit_identity_opts * src_opts,pkinit_identity_opts ** dest_opts)1527934SMark.Phalan@Sun.COM pkinit_dup_identity_opts(pkinit_identity_opts *src_opts,
1537934SMark.Phalan@Sun.COM pkinit_identity_opts **dest_opts)
1547934SMark.Phalan@Sun.COM {
1557934SMark.Phalan@Sun.COM pkinit_identity_opts *newopts;
1567934SMark.Phalan@Sun.COM krb5_error_code retval;
1577934SMark.Phalan@Sun.COM
1587934SMark.Phalan@Sun.COM *dest_opts = NULL;
1597934SMark.Phalan@Sun.COM retval = pkinit_init_identity_opts(&newopts);
1607934SMark.Phalan@Sun.COM if (retval)
1617934SMark.Phalan@Sun.COM return retval;
1627934SMark.Phalan@Sun.COM
1637934SMark.Phalan@Sun.COM retval = ENOMEM;
1647934SMark.Phalan@Sun.COM
1657934SMark.Phalan@Sun.COM if (src_opts->identity != NULL) {
1667934SMark.Phalan@Sun.COM newopts->identity = strdup(src_opts->identity);
1677934SMark.Phalan@Sun.COM if (newopts->identity == NULL)
1687934SMark.Phalan@Sun.COM goto cleanup;
1697934SMark.Phalan@Sun.COM }
1707934SMark.Phalan@Sun.COM
1717934SMark.Phalan@Sun.COM retval = copy_list(&newopts->anchors, src_opts->anchors);
1727934SMark.Phalan@Sun.COM if (retval)
1737934SMark.Phalan@Sun.COM goto cleanup;
1747934SMark.Phalan@Sun.COM
1757934SMark.Phalan@Sun.COM retval = copy_list(&newopts->intermediates,src_opts->intermediates);
1767934SMark.Phalan@Sun.COM if (retval)
1777934SMark.Phalan@Sun.COM goto cleanup;
1787934SMark.Phalan@Sun.COM
1797934SMark.Phalan@Sun.COM retval = copy_list(&newopts->crls, src_opts->crls);
1807934SMark.Phalan@Sun.COM if (retval)
1817934SMark.Phalan@Sun.COM goto cleanup;
1827934SMark.Phalan@Sun.COM
1837934SMark.Phalan@Sun.COM if (src_opts->ocsp != NULL) {
1847934SMark.Phalan@Sun.COM newopts->ocsp = strdup(src_opts->ocsp);
1857934SMark.Phalan@Sun.COM if (newopts->ocsp == NULL)
1867934SMark.Phalan@Sun.COM goto cleanup;
1877934SMark.Phalan@Sun.COM }
1887934SMark.Phalan@Sun.COM
1897934SMark.Phalan@Sun.COM if (src_opts->cert_filename != NULL) {
1907934SMark.Phalan@Sun.COM newopts->cert_filename = strdup(src_opts->cert_filename);
1917934SMark.Phalan@Sun.COM if (newopts->cert_filename == NULL)
1927934SMark.Phalan@Sun.COM goto cleanup;
1937934SMark.Phalan@Sun.COM }
1947934SMark.Phalan@Sun.COM
1957934SMark.Phalan@Sun.COM if (src_opts->key_filename != NULL) {
1967934SMark.Phalan@Sun.COM newopts->key_filename = strdup(src_opts->key_filename);
1977934SMark.Phalan@Sun.COM if (newopts->key_filename == NULL)
1987934SMark.Phalan@Sun.COM goto cleanup;
1997934SMark.Phalan@Sun.COM }
2007934SMark.Phalan@Sun.COM
2017934SMark.Phalan@Sun.COM #ifndef WITHOUT_PKCS11
2027934SMark.Phalan@Sun.COM if (src_opts->p11_module_name != NULL) {
2037934SMark.Phalan@Sun.COM newopts->p11_module_name = strdup(src_opts->p11_module_name);
2047934SMark.Phalan@Sun.COM if (newopts->p11_module_name == NULL)
2057934SMark.Phalan@Sun.COM goto cleanup;
2067934SMark.Phalan@Sun.COM }
2077934SMark.Phalan@Sun.COM
2087934SMark.Phalan@Sun.COM newopts->slotid = src_opts->slotid;
2097934SMark.Phalan@Sun.COM
2107934SMark.Phalan@Sun.COM if (src_opts->token_label != NULL) {
2117934SMark.Phalan@Sun.COM newopts->token_label = strdup(src_opts->token_label);
2127934SMark.Phalan@Sun.COM if (newopts->token_label == NULL)
2137934SMark.Phalan@Sun.COM goto cleanup;
2147934SMark.Phalan@Sun.COM }
2157934SMark.Phalan@Sun.COM
2167934SMark.Phalan@Sun.COM if (src_opts->cert_id_string != NULL) {
2177934SMark.Phalan@Sun.COM newopts->cert_id_string = strdup(src_opts->cert_id_string);
2187934SMark.Phalan@Sun.COM if (newopts->cert_id_string == NULL)
2197934SMark.Phalan@Sun.COM goto cleanup;
2207934SMark.Phalan@Sun.COM }
2217934SMark.Phalan@Sun.COM
2227934SMark.Phalan@Sun.COM if (src_opts->cert_label != NULL) {
2237934SMark.Phalan@Sun.COM newopts->cert_label = strdup(src_opts->cert_label);
2247934SMark.Phalan@Sun.COM if (newopts->cert_label == NULL)
2257934SMark.Phalan@Sun.COM goto cleanup;
2267934SMark.Phalan@Sun.COM }
22712941Swill.fiveash@oracle.com if (src_opts->PIN != NULL) {
22812941Swill.fiveash@oracle.com newopts->PIN = strdup(src_opts->PIN);
22912941Swill.fiveash@oracle.com if (newopts->PIN == NULL)
23012941Swill.fiveash@oracle.com goto cleanup;
23112941Swill.fiveash@oracle.com }
2327934SMark.Phalan@Sun.COM #endif
2337934SMark.Phalan@Sun.COM
2347934SMark.Phalan@Sun.COM
2357934SMark.Phalan@Sun.COM *dest_opts = newopts;
2367934SMark.Phalan@Sun.COM return 0;
2377934SMark.Phalan@Sun.COM cleanup:
2387934SMark.Phalan@Sun.COM pkinit_fini_identity_opts(newopts);
2397934SMark.Phalan@Sun.COM return retval;
2407934SMark.Phalan@Sun.COM }
2417934SMark.Phalan@Sun.COM
2427934SMark.Phalan@Sun.COM void
pkinit_fini_identity_opts(pkinit_identity_opts * idopts)2437934SMark.Phalan@Sun.COM pkinit_fini_identity_opts(pkinit_identity_opts *idopts)
2447934SMark.Phalan@Sun.COM {
2457934SMark.Phalan@Sun.COM if (idopts == NULL)
2467934SMark.Phalan@Sun.COM return;
2477934SMark.Phalan@Sun.COM
2487934SMark.Phalan@Sun.COM if (idopts->identity != NULL)
2497934SMark.Phalan@Sun.COM free(idopts->identity);
2507934SMark.Phalan@Sun.COM free_list(idopts->anchors);
2517934SMark.Phalan@Sun.COM free_list(idopts->intermediates);
2527934SMark.Phalan@Sun.COM free_list(idopts->crls);
2537934SMark.Phalan@Sun.COM free_list(idopts->identity_alt);
2547934SMark.Phalan@Sun.COM
2557934SMark.Phalan@Sun.COM if (idopts->cert_filename != NULL)
2567934SMark.Phalan@Sun.COM free(idopts->cert_filename);
2577934SMark.Phalan@Sun.COM if (idopts->key_filename != NULL)
2587934SMark.Phalan@Sun.COM free(idopts->key_filename);
2597934SMark.Phalan@Sun.COM #ifndef WITHOUT_PKCS11
2607934SMark.Phalan@Sun.COM if (idopts->p11_module_name != NULL)
2617934SMark.Phalan@Sun.COM free(idopts->p11_module_name);
2627934SMark.Phalan@Sun.COM if (idopts->token_label != NULL)
2637934SMark.Phalan@Sun.COM free(idopts->token_label);
2647934SMark.Phalan@Sun.COM if (idopts->cert_id_string != NULL)
2657934SMark.Phalan@Sun.COM free(idopts->cert_id_string);
2667934SMark.Phalan@Sun.COM if (idopts->cert_label != NULL)
2677934SMark.Phalan@Sun.COM free(idopts->cert_label);
26812941Swill.fiveash@oracle.com if (idopts->PIN != NULL) {
26912941Swill.fiveash@oracle.com (void) memset(idopts->PIN, 0, strlen(idopts->PIN));
27012941Swill.fiveash@oracle.com free(idopts->PIN);
27112941Swill.fiveash@oracle.com }
2727934SMark.Phalan@Sun.COM #endif
2737934SMark.Phalan@Sun.COM free(idopts);
2747934SMark.Phalan@Sun.COM }
2757934SMark.Phalan@Sun.COM
2767934SMark.Phalan@Sun.COM #ifndef WITHOUT_PKCS11
2777934SMark.Phalan@Sun.COM /* ARGSUSED */
2787934SMark.Phalan@Sun.COM static krb5_error_code
parse_pkcs11_options(krb5_context context,pkinit_identity_opts * idopts,const char * residual)2797934SMark.Phalan@Sun.COM parse_pkcs11_options(krb5_context context,
2807934SMark.Phalan@Sun.COM pkinit_identity_opts *idopts,
2817934SMark.Phalan@Sun.COM const char *residual)
2827934SMark.Phalan@Sun.COM {
2837934SMark.Phalan@Sun.COM char *s, *cp, *vp;
2847934SMark.Phalan@Sun.COM krb5_error_code retval = ENOMEM;
2857934SMark.Phalan@Sun.COM
2867934SMark.Phalan@Sun.COM if (residual == NULL || residual[0] == '\0')
2877934SMark.Phalan@Sun.COM return 0;
2887934SMark.Phalan@Sun.COM
2897934SMark.Phalan@Sun.COM /* Split string into attr=value substrings */
2907934SMark.Phalan@Sun.COM s = strdup(residual);
2917934SMark.Phalan@Sun.COM if (s == NULL)
2927934SMark.Phalan@Sun.COM return retval;
2937934SMark.Phalan@Sun.COM
2947934SMark.Phalan@Sun.COM for ((cp = strtok(s, ":")); cp; (cp = strtok(NULL, ":"))) {
2957934SMark.Phalan@Sun.COM vp = strchr(cp, '=');
2967934SMark.Phalan@Sun.COM
2977934SMark.Phalan@Sun.COM /* If there is no "=", this is a pkcs11 module name */
2987934SMark.Phalan@Sun.COM if (vp == NULL) {
2997934SMark.Phalan@Sun.COM if (idopts->p11_module_name != NULL)
3007934SMark.Phalan@Sun.COM free(idopts->p11_module_name);
3017934SMark.Phalan@Sun.COM idopts->p11_module_name = strdup(cp);
3027934SMark.Phalan@Sun.COM if (idopts->p11_module_name == NULL)
3037934SMark.Phalan@Sun.COM goto cleanup;
3047934SMark.Phalan@Sun.COM continue;
3057934SMark.Phalan@Sun.COM }
3067934SMark.Phalan@Sun.COM *vp++ = '\0';
3077934SMark.Phalan@Sun.COM if (!strcmp(cp, "module_name")) {
3087934SMark.Phalan@Sun.COM if (idopts->p11_module_name != NULL)
3097934SMark.Phalan@Sun.COM free(idopts->p11_module_name);
3107934SMark.Phalan@Sun.COM idopts->p11_module_name = strdup(vp);
3117934SMark.Phalan@Sun.COM if (idopts->p11_module_name == NULL)
3127934SMark.Phalan@Sun.COM goto cleanup;
3137934SMark.Phalan@Sun.COM } else if (!strcmp(cp, "slotid")) {
3147934SMark.Phalan@Sun.COM long slotid = strtol(vp, NULL, 10);
3157934SMark.Phalan@Sun.COM if ((slotid == LONG_MIN || slotid == LONG_MAX) && errno != 0) {
3167934SMark.Phalan@Sun.COM retval = EINVAL;
3177934SMark.Phalan@Sun.COM goto cleanup;
3187934SMark.Phalan@Sun.COM }
3197934SMark.Phalan@Sun.COM if ((long) (int) slotid != slotid) {
3207934SMark.Phalan@Sun.COM retval = EINVAL;
3217934SMark.Phalan@Sun.COM goto cleanup;
3227934SMark.Phalan@Sun.COM }
3237934SMark.Phalan@Sun.COM idopts->slotid = slotid;
3247934SMark.Phalan@Sun.COM } else if (!strcmp(cp, "token")) {
3257934SMark.Phalan@Sun.COM if (idopts->token_label != NULL)
3267934SMark.Phalan@Sun.COM free(idopts->token_label);
3277934SMark.Phalan@Sun.COM idopts->token_label = strdup(vp);
3287934SMark.Phalan@Sun.COM if (idopts->token_label == NULL)
3297934SMark.Phalan@Sun.COM goto cleanup;
3307934SMark.Phalan@Sun.COM } else if (!strcmp(cp, "certid")) {
3317934SMark.Phalan@Sun.COM if (idopts->cert_id_string != NULL)
3327934SMark.Phalan@Sun.COM free(idopts->cert_id_string);
3337934SMark.Phalan@Sun.COM idopts->cert_id_string = strdup(vp);
3347934SMark.Phalan@Sun.COM if (idopts->cert_id_string == NULL)
3357934SMark.Phalan@Sun.COM goto cleanup;
3367934SMark.Phalan@Sun.COM } else if (!strcmp(cp, "certlabel")) {
3377934SMark.Phalan@Sun.COM if (idopts->cert_label != NULL)
3387934SMark.Phalan@Sun.COM free(idopts->cert_label);
3397934SMark.Phalan@Sun.COM idopts->cert_label = strdup(vp);
3407934SMark.Phalan@Sun.COM if (idopts->cert_label == NULL)
3417934SMark.Phalan@Sun.COM goto cleanup;
3427934SMark.Phalan@Sun.COM }
3437934SMark.Phalan@Sun.COM }
3447934SMark.Phalan@Sun.COM retval = 0;
3457934SMark.Phalan@Sun.COM cleanup:
3467934SMark.Phalan@Sun.COM free(s);
3477934SMark.Phalan@Sun.COM return retval;
3487934SMark.Phalan@Sun.COM }
3497934SMark.Phalan@Sun.COM #endif
3507934SMark.Phalan@Sun.COM
3517934SMark.Phalan@Sun.COM /* ARGSUSED */
3527934SMark.Phalan@Sun.COM static krb5_error_code
parse_fs_options(krb5_context context,pkinit_identity_opts * idopts,const char * residual)3537934SMark.Phalan@Sun.COM parse_fs_options(krb5_context context,
3547934SMark.Phalan@Sun.COM pkinit_identity_opts *idopts,
3557934SMark.Phalan@Sun.COM const char *residual)
3567934SMark.Phalan@Sun.COM {
3577934SMark.Phalan@Sun.COM char *certname, *keyname;
3587934SMark.Phalan@Sun.COM krb5_error_code retval = ENOMEM;
3597934SMark.Phalan@Sun.COM
3607934SMark.Phalan@Sun.COM if (residual == NULL || residual[0] == '\0')
3617934SMark.Phalan@Sun.COM return 0;
3627934SMark.Phalan@Sun.COM
3637934SMark.Phalan@Sun.COM certname = strdup(residual);
3647934SMark.Phalan@Sun.COM if (certname == NULL)
3657934SMark.Phalan@Sun.COM goto cleanup;
3667934SMark.Phalan@Sun.COM
3677934SMark.Phalan@Sun.COM certname = strtok(certname, ",");
3687934SMark.Phalan@Sun.COM keyname = strtok(NULL, ",");
3697934SMark.Phalan@Sun.COM
3707934SMark.Phalan@Sun.COM idopts->cert_filename = strdup(certname);
3717934SMark.Phalan@Sun.COM if (idopts->cert_filename == NULL)
3727934SMark.Phalan@Sun.COM goto cleanup;
3737934SMark.Phalan@Sun.COM
3747934SMark.Phalan@Sun.COM idopts->key_filename = strdup(keyname ? keyname : certname);
3757934SMark.Phalan@Sun.COM if (idopts->key_filename == NULL)
3767934SMark.Phalan@Sun.COM goto cleanup;
3777934SMark.Phalan@Sun.COM
3787934SMark.Phalan@Sun.COM retval = 0;
3797934SMark.Phalan@Sun.COM cleanup:
3807934SMark.Phalan@Sun.COM if (certname != NULL)
3817934SMark.Phalan@Sun.COM free(certname);
3827934SMark.Phalan@Sun.COM return retval;
3837934SMark.Phalan@Sun.COM }
3847934SMark.Phalan@Sun.COM
3857934SMark.Phalan@Sun.COM /* ARGSUSED */
3867934SMark.Phalan@Sun.COM static krb5_error_code
parse_pkcs12_options(krb5_context context,pkinit_identity_opts * idopts,const char * residual)3877934SMark.Phalan@Sun.COM parse_pkcs12_options(krb5_context context,
3887934SMark.Phalan@Sun.COM pkinit_identity_opts *idopts,
3897934SMark.Phalan@Sun.COM const char *residual)
3907934SMark.Phalan@Sun.COM {
3917934SMark.Phalan@Sun.COM krb5_error_code retval = ENOMEM;
3927934SMark.Phalan@Sun.COM
3937934SMark.Phalan@Sun.COM if (residual == NULL || residual[0] == '\0')
3947934SMark.Phalan@Sun.COM return 0;
3957934SMark.Phalan@Sun.COM
3967934SMark.Phalan@Sun.COM idopts->cert_filename = strdup(residual);
3977934SMark.Phalan@Sun.COM if (idopts->cert_filename == NULL)
3987934SMark.Phalan@Sun.COM goto cleanup;
3997934SMark.Phalan@Sun.COM
4007934SMark.Phalan@Sun.COM idopts->key_filename = strdup(residual);
4017934SMark.Phalan@Sun.COM if (idopts->key_filename == NULL)
4027934SMark.Phalan@Sun.COM goto cleanup;
4037934SMark.Phalan@Sun.COM
4047934SMark.Phalan@Sun.COM pkiDebug("%s: cert_filename '%s' key_filename '%s'\n",
4057934SMark.Phalan@Sun.COM __FUNCTION__, idopts->cert_filename,
4067934SMark.Phalan@Sun.COM idopts->key_filename);
4077934SMark.Phalan@Sun.COM retval = 0;
4087934SMark.Phalan@Sun.COM cleanup:
4097934SMark.Phalan@Sun.COM return retval;
4107934SMark.Phalan@Sun.COM }
4117934SMark.Phalan@Sun.COM
4127934SMark.Phalan@Sun.COM static krb5_error_code
process_option_identity(krb5_context context,pkinit_plg_crypto_context plg_cryptoctx,pkinit_req_crypto_context req_cryptoctx,pkinit_identity_opts * idopts,pkinit_identity_crypto_context id_cryptoctx,const char * value)4137934SMark.Phalan@Sun.COM process_option_identity(krb5_context context,
4147934SMark.Phalan@Sun.COM pkinit_plg_crypto_context plg_cryptoctx,
4157934SMark.Phalan@Sun.COM pkinit_req_crypto_context req_cryptoctx,
4167934SMark.Phalan@Sun.COM pkinit_identity_opts *idopts,
4177934SMark.Phalan@Sun.COM pkinit_identity_crypto_context id_cryptoctx,
4187934SMark.Phalan@Sun.COM const char *value)
4197934SMark.Phalan@Sun.COM {
4207934SMark.Phalan@Sun.COM const char *residual;
4217934SMark.Phalan@Sun.COM int idtype;
4227934SMark.Phalan@Sun.COM krb5_error_code retval = 0;
4237934SMark.Phalan@Sun.COM
4247934SMark.Phalan@Sun.COM pkiDebug("%s: processing value '%s'\n",
4257934SMark.Phalan@Sun.COM __FUNCTION__, value ? value : "NULL");
4267934SMark.Phalan@Sun.COM if (value == NULL)
4277934SMark.Phalan@Sun.COM return EINVAL;
4287934SMark.Phalan@Sun.COM
4297934SMark.Phalan@Sun.COM residual = strchr(value, ':');
4307934SMark.Phalan@Sun.COM if (residual != NULL) {
4317934SMark.Phalan@Sun.COM unsigned int typelen;
4327934SMark.Phalan@Sun.COM residual++; /* skip past colon */
4337934SMark.Phalan@Sun.COM typelen = residual - value;
4347934SMark.Phalan@Sun.COM if (strncmp(value, "FILE:", typelen) == 0) {
4357934SMark.Phalan@Sun.COM idtype = IDTYPE_FILE;
4367934SMark.Phalan@Sun.COM #ifndef WITHOUT_PKCS11
4377934SMark.Phalan@Sun.COM } else if (strncmp(value, "PKCS11:", typelen) == 0) {
4387934SMark.Phalan@Sun.COM idtype = IDTYPE_PKCS11;
4397934SMark.Phalan@Sun.COM #endif
4407934SMark.Phalan@Sun.COM } else if (strncmp(value, "PKCS12:", typelen) == 0) {
4417934SMark.Phalan@Sun.COM idtype = IDTYPE_PKCS12;
4427934SMark.Phalan@Sun.COM } else if (strncmp(value, "DIR:", typelen) == 0) {
4437934SMark.Phalan@Sun.COM idtype = IDTYPE_DIR;
4447934SMark.Phalan@Sun.COM } else if (strncmp(value, "ENV:", typelen) == 0) {
4457934SMark.Phalan@Sun.COM idtype = IDTYPE_ENVVAR;
4467934SMark.Phalan@Sun.COM } else {
4477934SMark.Phalan@Sun.COM pkiDebug("%s: Unsupported type while processing '%s'\n",
4487934SMark.Phalan@Sun.COM __FUNCTION__, value);
4497934SMark.Phalan@Sun.COM krb5_set_error_message(context, KRB5_PREAUTH_FAILED,
4507934SMark.Phalan@Sun.COM "Unsupported type while processing '%s'\n",
4517934SMark.Phalan@Sun.COM value);
4527934SMark.Phalan@Sun.COM return KRB5_PREAUTH_FAILED;
4537934SMark.Phalan@Sun.COM }
4547934SMark.Phalan@Sun.COM } else {
4557934SMark.Phalan@Sun.COM idtype = IDTYPE_FILE;
4567934SMark.Phalan@Sun.COM residual = value;
4577934SMark.Phalan@Sun.COM }
4587934SMark.Phalan@Sun.COM
4597934SMark.Phalan@Sun.COM idopts->idtype = idtype;
4607934SMark.Phalan@Sun.COM pkiDebug("%s: idtype is %s\n", __FUNCTION__, idtype2string(idopts->idtype));
4617934SMark.Phalan@Sun.COM switch (idtype) {
4627934SMark.Phalan@Sun.COM case IDTYPE_ENVVAR: {
4637934SMark.Phalan@Sun.COM /* Solaris Kerberos: Improved error messages */
4647934SMark.Phalan@Sun.COM char *envvar = getenv(residual);
4657934SMark.Phalan@Sun.COM if (envvar == NULL) {
4667934SMark.Phalan@Sun.COM krb5_set_error_message(context, EINVAL,
4677934SMark.Phalan@Sun.COM gettext("failed to find environmental variable \'%s\'"),
4687934SMark.Phalan@Sun.COM residual);
4697934SMark.Phalan@Sun.COM return EINVAL;
4707934SMark.Phalan@Sun.COM }
4717934SMark.Phalan@Sun.COM return process_option_identity(context, plg_cryptoctx,
4727934SMark.Phalan@Sun.COM req_cryptoctx, idopts, id_cryptoctx,
4737934SMark.Phalan@Sun.COM envvar);
4747934SMark.Phalan@Sun.COM /* Solaris Kerberos: not reached */
4757934SMark.Phalan@Sun.COM }
4767934SMark.Phalan@Sun.COM case IDTYPE_FILE:
4777934SMark.Phalan@Sun.COM retval = parse_fs_options(context, idopts, residual);
4787934SMark.Phalan@Sun.COM break;
4797934SMark.Phalan@Sun.COM case IDTYPE_PKCS12:
4807934SMark.Phalan@Sun.COM retval = parse_pkcs12_options(context, idopts, residual);
4817934SMark.Phalan@Sun.COM break;
4827934SMark.Phalan@Sun.COM #ifndef WITHOUT_PKCS11
4837934SMark.Phalan@Sun.COM case IDTYPE_PKCS11:
4847934SMark.Phalan@Sun.COM retval = parse_pkcs11_options(context, idopts, residual);
4857934SMark.Phalan@Sun.COM break;
4867934SMark.Phalan@Sun.COM #endif
4877934SMark.Phalan@Sun.COM case IDTYPE_DIR:
4887934SMark.Phalan@Sun.COM idopts->cert_filename = strdup(residual);
4897934SMark.Phalan@Sun.COM if (idopts->cert_filename == NULL)
4907934SMark.Phalan@Sun.COM retval = ENOMEM;
4917934SMark.Phalan@Sun.COM break;
4927934SMark.Phalan@Sun.COM default:
4937934SMark.Phalan@Sun.COM krb5_set_error_message(context, KRB5_PREAUTH_FAILED,
4947934SMark.Phalan@Sun.COM "Internal error parsing X509_user_identity\n");
4957934SMark.Phalan@Sun.COM retval = EINVAL;
4967934SMark.Phalan@Sun.COM break;
4977934SMark.Phalan@Sun.COM }
4987934SMark.Phalan@Sun.COM return retval;
4997934SMark.Phalan@Sun.COM }
5007934SMark.Phalan@Sun.COM
5017934SMark.Phalan@Sun.COM static krb5_error_code
process_option_ca_crl(krb5_context context,pkinit_plg_crypto_context plg_cryptoctx,pkinit_req_crypto_context req_cryptoctx,pkinit_identity_opts * idopts,pkinit_identity_crypto_context id_cryptoctx,const char * value,int catype)5027934SMark.Phalan@Sun.COM process_option_ca_crl(krb5_context context,
5037934SMark.Phalan@Sun.COM pkinit_plg_crypto_context plg_cryptoctx,
5047934SMark.Phalan@Sun.COM pkinit_req_crypto_context req_cryptoctx,
5057934SMark.Phalan@Sun.COM pkinit_identity_opts *idopts,
5067934SMark.Phalan@Sun.COM pkinit_identity_crypto_context id_cryptoctx,
5077934SMark.Phalan@Sun.COM const char *value,
5087934SMark.Phalan@Sun.COM int catype)
5097934SMark.Phalan@Sun.COM {
5107934SMark.Phalan@Sun.COM char *residual;
5117934SMark.Phalan@Sun.COM unsigned int typelen;
5127934SMark.Phalan@Sun.COM int idtype;
5137934SMark.Phalan@Sun.COM
5147934SMark.Phalan@Sun.COM pkiDebug("%s: processing catype %s, value '%s'\n",
5157934SMark.Phalan@Sun.COM __FUNCTION__, catype2string(catype), value);
5167934SMark.Phalan@Sun.COM residual = strchr(value, ':');
5177934SMark.Phalan@Sun.COM if (residual == NULL) {
5187934SMark.Phalan@Sun.COM pkiDebug("No type given for '%s'\n", value);
5197934SMark.Phalan@Sun.COM return EINVAL;
5207934SMark.Phalan@Sun.COM }
5217934SMark.Phalan@Sun.COM residual++; /* skip past colon */
5227934SMark.Phalan@Sun.COM typelen = residual - value;
5237934SMark.Phalan@Sun.COM if (strncmp(value, "FILE:", typelen) == 0) {
5247934SMark.Phalan@Sun.COM idtype = IDTYPE_FILE;
5257934SMark.Phalan@Sun.COM } else if (strncmp(value, "DIR:", typelen) == 0) {
5267934SMark.Phalan@Sun.COM idtype = IDTYPE_DIR;
5277934SMark.Phalan@Sun.COM } else {
5287934SMark.Phalan@Sun.COM return ENOTSUP;
5297934SMark.Phalan@Sun.COM }
5307934SMark.Phalan@Sun.COM return crypto_load_cas_and_crls(context,
5317934SMark.Phalan@Sun.COM plg_cryptoctx,
5327934SMark.Phalan@Sun.COM req_cryptoctx,
5337934SMark.Phalan@Sun.COM idopts, id_cryptoctx,
5347934SMark.Phalan@Sun.COM idtype, catype, residual);
5357934SMark.Phalan@Sun.COM }
5367934SMark.Phalan@Sun.COM
5377934SMark.Phalan@Sun.COM static krb5_error_code
pkinit_identity_process_option(krb5_context context,pkinit_plg_crypto_context plg_cryptoctx,pkinit_req_crypto_context req_cryptoctx,pkinit_identity_opts * idopts,pkinit_identity_crypto_context id_cryptoctx,int attr,const char * value)5387934SMark.Phalan@Sun.COM pkinit_identity_process_option(krb5_context context,
5397934SMark.Phalan@Sun.COM pkinit_plg_crypto_context plg_cryptoctx,
5407934SMark.Phalan@Sun.COM pkinit_req_crypto_context req_cryptoctx,
5417934SMark.Phalan@Sun.COM pkinit_identity_opts *idopts,
5427934SMark.Phalan@Sun.COM pkinit_identity_crypto_context id_cryptoctx,
5437934SMark.Phalan@Sun.COM int attr,
5447934SMark.Phalan@Sun.COM const char *value)
5457934SMark.Phalan@Sun.COM {
5467934SMark.Phalan@Sun.COM krb5_error_code retval = 0;
5477934SMark.Phalan@Sun.COM
5487934SMark.Phalan@Sun.COM switch (attr) {
5497934SMark.Phalan@Sun.COM case PKINIT_ID_OPT_USER_IDENTITY:
5507934SMark.Phalan@Sun.COM retval = process_option_identity(context, plg_cryptoctx,
5517934SMark.Phalan@Sun.COM req_cryptoctx, idopts,
5527934SMark.Phalan@Sun.COM id_cryptoctx, value);
5537934SMark.Phalan@Sun.COM break;
5547934SMark.Phalan@Sun.COM case PKINIT_ID_OPT_ANCHOR_CAS:
5557934SMark.Phalan@Sun.COM retval = process_option_ca_crl(context, plg_cryptoctx,
5567934SMark.Phalan@Sun.COM req_cryptoctx, idopts,
5577934SMark.Phalan@Sun.COM id_cryptoctx, value,
5587934SMark.Phalan@Sun.COM CATYPE_ANCHORS);
5597934SMark.Phalan@Sun.COM break;
5607934SMark.Phalan@Sun.COM case PKINIT_ID_OPT_INTERMEDIATE_CAS:
5617934SMark.Phalan@Sun.COM retval = process_option_ca_crl(context, plg_cryptoctx,
5627934SMark.Phalan@Sun.COM req_cryptoctx, idopts,
5637934SMark.Phalan@Sun.COM id_cryptoctx,
5647934SMark.Phalan@Sun.COM value, CATYPE_INTERMEDIATES);
5657934SMark.Phalan@Sun.COM break;
5667934SMark.Phalan@Sun.COM case PKINIT_ID_OPT_CRLS:
5677934SMark.Phalan@Sun.COM retval = process_option_ca_crl(context, plg_cryptoctx,
5687934SMark.Phalan@Sun.COM req_cryptoctx, idopts,
5697934SMark.Phalan@Sun.COM id_cryptoctx,
5707934SMark.Phalan@Sun.COM value, CATYPE_CRLS);
5717934SMark.Phalan@Sun.COM break;
5727934SMark.Phalan@Sun.COM case PKINIT_ID_OPT_OCSP:
5737934SMark.Phalan@Sun.COM retval = ENOTSUP;
5747934SMark.Phalan@Sun.COM break;
5757934SMark.Phalan@Sun.COM default:
5767934SMark.Phalan@Sun.COM retval = EINVAL;
5777934SMark.Phalan@Sun.COM break;
5787934SMark.Phalan@Sun.COM }
5797934SMark.Phalan@Sun.COM return retval;
5807934SMark.Phalan@Sun.COM }
5817934SMark.Phalan@Sun.COM
5827934SMark.Phalan@Sun.COM krb5_error_code
pkinit_identity_initialize(krb5_context context,pkinit_plg_crypto_context plg_cryptoctx,pkinit_req_crypto_context req_cryptoctx,pkinit_identity_opts * idopts,pkinit_identity_crypto_context id_cryptoctx,int do_matching,krb5_principal princ)5837934SMark.Phalan@Sun.COM pkinit_identity_initialize(krb5_context context,
5847934SMark.Phalan@Sun.COM pkinit_plg_crypto_context plg_cryptoctx,
5857934SMark.Phalan@Sun.COM pkinit_req_crypto_context req_cryptoctx,
5867934SMark.Phalan@Sun.COM pkinit_identity_opts *idopts,
5877934SMark.Phalan@Sun.COM pkinit_identity_crypto_context id_cryptoctx,
5887934SMark.Phalan@Sun.COM int do_matching,
5897934SMark.Phalan@Sun.COM krb5_principal princ)
5907934SMark.Phalan@Sun.COM {
5917934SMark.Phalan@Sun.COM krb5_error_code retval = EINVAL;
5927934SMark.Phalan@Sun.COM int i;
5937934SMark.Phalan@Sun.COM
5947934SMark.Phalan@Sun.COM pkiDebug("%s: %p %p %p\n", __FUNCTION__, context, idopts, id_cryptoctx);
5957934SMark.Phalan@Sun.COM if (idopts == NULL || id_cryptoctx == NULL)
5967934SMark.Phalan@Sun.COM goto errout;
5977934SMark.Phalan@Sun.COM
5987934SMark.Phalan@Sun.COM /*
5997934SMark.Phalan@Sun.COM * If identity was specified, use that. (For the kdc, this
6007934SMark.Phalan@Sun.COM * is specified as pkinit_identity in the kdc.conf. For users,
6017934SMark.Phalan@Sun.COM * this is specified on the command line via X509_user_identity.)
6027934SMark.Phalan@Sun.COM * If a user did not specify identity on the command line,
6037934SMark.Phalan@Sun.COM * then we will try alternatives which may have been specified
6047934SMark.Phalan@Sun.COM * in the config file.
6057934SMark.Phalan@Sun.COM */
6067934SMark.Phalan@Sun.COM if (idopts->identity != NULL) {
6077934SMark.Phalan@Sun.COM retval = pkinit_identity_process_option(context, plg_cryptoctx,
6087934SMark.Phalan@Sun.COM req_cryptoctx, idopts,
6097934SMark.Phalan@Sun.COM id_cryptoctx,
6107934SMark.Phalan@Sun.COM PKINIT_ID_OPT_USER_IDENTITY,
6117934SMark.Phalan@Sun.COM idopts->identity);
6127934SMark.Phalan@Sun.COM } else if (idopts->identity_alt != NULL) {
6137934SMark.Phalan@Sun.COM for (i = 0; retval != 0 && idopts->identity_alt[i] != NULL; i++)
6147934SMark.Phalan@Sun.COM retval = pkinit_identity_process_option(context, plg_cryptoctx,
6157934SMark.Phalan@Sun.COM req_cryptoctx, idopts,
6167934SMark.Phalan@Sun.COM id_cryptoctx,
6177934SMark.Phalan@Sun.COM PKINIT_ID_OPT_USER_IDENTITY,
6187934SMark.Phalan@Sun.COM idopts->identity_alt[i]);
6197934SMark.Phalan@Sun.COM } else {
6207934SMark.Phalan@Sun.COM pkiDebug("%s: no user identity options specified\n", __FUNCTION__);
6217934SMark.Phalan@Sun.COM goto errout;
6227934SMark.Phalan@Sun.COM }
6237934SMark.Phalan@Sun.COM if (retval)
6247934SMark.Phalan@Sun.COM goto errout;
6257934SMark.Phalan@Sun.COM
6267934SMark.Phalan@Sun.COM retval = crypto_load_certs(context, plg_cryptoctx, req_cryptoctx,
627*12945Swill.fiveash@oracle.com idopts, id_cryptoctx, princ, do_matching);
6287934SMark.Phalan@Sun.COM if (retval)
6297934SMark.Phalan@Sun.COM goto errout;
6307934SMark.Phalan@Sun.COM
6317934SMark.Phalan@Sun.COM if (do_matching) {
6327934SMark.Phalan@Sun.COM retval = pkinit_cert_matching(context, plg_cryptoctx, req_cryptoctx,
633*12945Swill.fiveash@oracle.com id_cryptoctx, princ, TRUE);
6347934SMark.Phalan@Sun.COM if (retval) {
6357934SMark.Phalan@Sun.COM pkiDebug("%s: No matching certificate found\n", __FUNCTION__);
6367934SMark.Phalan@Sun.COM (void) crypto_free_cert_info(context, plg_cryptoctx, req_cryptoctx,
6377934SMark.Phalan@Sun.COM id_cryptoctx);
6387934SMark.Phalan@Sun.COM goto errout;
6397934SMark.Phalan@Sun.COM }
6407934SMark.Phalan@Sun.COM } else {
6417934SMark.Phalan@Sun.COM /* Tell crypto code to use the "default" */
6427934SMark.Phalan@Sun.COM retval = crypto_cert_select_default(context, plg_cryptoctx,
6437934SMark.Phalan@Sun.COM req_cryptoctx, id_cryptoctx);
6447934SMark.Phalan@Sun.COM if (retval) {
6457934SMark.Phalan@Sun.COM pkiDebug("%s: Failed while selecting default certificate\n",
6467934SMark.Phalan@Sun.COM __FUNCTION__);
6477934SMark.Phalan@Sun.COM (void) crypto_free_cert_info(context, plg_cryptoctx, req_cryptoctx,
6487934SMark.Phalan@Sun.COM id_cryptoctx);
6497934SMark.Phalan@Sun.COM goto errout;
6507934SMark.Phalan@Sun.COM }
6517934SMark.Phalan@Sun.COM }
6527934SMark.Phalan@Sun.COM
6537934SMark.Phalan@Sun.COM retval = crypto_free_cert_info(context, plg_cryptoctx, req_cryptoctx,
6547934SMark.Phalan@Sun.COM id_cryptoctx);
6557934SMark.Phalan@Sun.COM if (retval)
6567934SMark.Phalan@Sun.COM goto errout;
6577934SMark.Phalan@Sun.COM
6587934SMark.Phalan@Sun.COM for (i = 0; idopts->anchors != NULL && idopts->anchors[i] != NULL; i++) {
6597934SMark.Phalan@Sun.COM retval = pkinit_identity_process_option(context, plg_cryptoctx,
6607934SMark.Phalan@Sun.COM req_cryptoctx, idopts,
6617934SMark.Phalan@Sun.COM id_cryptoctx,
6627934SMark.Phalan@Sun.COM PKINIT_ID_OPT_ANCHOR_CAS,
6637934SMark.Phalan@Sun.COM idopts->anchors[i]);
6647934SMark.Phalan@Sun.COM if (retval)
6657934SMark.Phalan@Sun.COM goto errout;
6667934SMark.Phalan@Sun.COM }
6677934SMark.Phalan@Sun.COM for (i = 0; idopts->intermediates != NULL
6687934SMark.Phalan@Sun.COM && idopts->intermediates[i] != NULL; i++) {
6697934SMark.Phalan@Sun.COM retval = pkinit_identity_process_option(context, plg_cryptoctx,
6707934SMark.Phalan@Sun.COM req_cryptoctx, idopts,
6717934SMark.Phalan@Sun.COM id_cryptoctx,
6727934SMark.Phalan@Sun.COM PKINIT_ID_OPT_INTERMEDIATE_CAS,
6737934SMark.Phalan@Sun.COM idopts->intermediates[i]);
6747934SMark.Phalan@Sun.COM if (retval)
6757934SMark.Phalan@Sun.COM goto errout;
6767934SMark.Phalan@Sun.COM }
6777934SMark.Phalan@Sun.COM for (i = 0; idopts->crls != NULL && idopts->crls[i] != NULL; i++) {
6787934SMark.Phalan@Sun.COM retval = pkinit_identity_process_option(context, plg_cryptoctx,
6797934SMark.Phalan@Sun.COM req_cryptoctx, idopts,
6807934SMark.Phalan@Sun.COM id_cryptoctx,
6817934SMark.Phalan@Sun.COM PKINIT_ID_OPT_CRLS,
6827934SMark.Phalan@Sun.COM idopts->crls[i]);
6837934SMark.Phalan@Sun.COM if (retval)
6847934SMark.Phalan@Sun.COM goto errout;
6857934SMark.Phalan@Sun.COM }
6867934SMark.Phalan@Sun.COM if (idopts->ocsp != NULL) {
6877934SMark.Phalan@Sun.COM retval = pkinit_identity_process_option(context, plg_cryptoctx,
6887934SMark.Phalan@Sun.COM req_cryptoctx, idopts,
6897934SMark.Phalan@Sun.COM id_cryptoctx,
6907934SMark.Phalan@Sun.COM PKINIT_ID_OPT_OCSP,
6917934SMark.Phalan@Sun.COM idopts->ocsp);
6927934SMark.Phalan@Sun.COM if (retval)
6937934SMark.Phalan@Sun.COM goto errout;
6947934SMark.Phalan@Sun.COM }
6957934SMark.Phalan@Sun.COM
6967934SMark.Phalan@Sun.COM errout:
6977934SMark.Phalan@Sun.COM return retval;
6987934SMark.Phalan@Sun.COM }
6997934SMark.Phalan@Sun.COM
700