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) { krb5_error_code retval = 0; switch (attr) { case PKINIT_ID_OPT_USER_IDENTITY: retval = process_option_identity(context, plg_cryptoctx, req_cryptoctx, idopts, id_cryptoctx, value); break; case PKINIT_ID_OPT_ANCHOR_CAS: retval = process_option_ca_crl(context, plg_cryptoctx, req_cryptoctx, idopts, id_cryptoctx, value, CATYPE_ANCHORS); break; case PKINIT_ID_OPT_INTERMEDIATE_CAS: retval = process_option_ca_crl(context, plg_cryptoctx, req_cryptoctx, idopts, id_cryptoctx, value, CATYPE_INTERMEDIATES); break; case PKINIT_ID_OPT_CRLS: retval = process_option_ca_crl(context, plg_cryptoctx, req_cryptoctx, idopts, id_cryptoctx, value, CATYPE_CRLS); break; case PKINIT_ID_OPT_OCSP: retval = ENOTSUP; break; default: retval = EINVAL; break; } return retval; }
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) { const char *residual; int idtype; krb5_error_code retval = 0; pkiDebug("%s: processing value '%s'\n", __FUNCTION__, value ? value : "NULL"); if (value == NULL) return EINVAL; residual = strchr(value, ':'); if (residual != NULL) { unsigned int typelen; residual++; /* skip past colon */ typelen = residual - value; if (strncmp(value, "FILE:", typelen) == 0) { idtype = IDTYPE_FILE; #ifndef WITHOUT_PKCS11 } else if (strncmp(value, "PKCS11:", typelen) == 0) { idtype = IDTYPE_PKCS11; #endif } else if (strncmp(value, "PKCS12:", typelen) == 0) { idtype = IDTYPE_PKCS12; } else if (strncmp(value, "DIR:", typelen) == 0) { idtype = IDTYPE_DIR; } else if (strncmp(value, "ENV:", typelen) == 0) { idtype = IDTYPE_ENVVAR; } else { pkiDebug("%s: Unsupported type while processing '%s'\n", __FUNCTION__, value); krb5_set_error_message(context, KRB5_PREAUTH_FAILED, "Unsupported type while processing '%s'\n", value); return KRB5_PREAUTH_FAILED; } } else { idtype = IDTYPE_FILE; residual = value; } idopts->idtype = idtype; pkiDebug("%s: idtype is %s\n", __FUNCTION__, idtype2string(idopts->idtype)); switch (idtype) { case IDTYPE_ENVVAR: return process_option_identity(context, plg_cryptoctx, req_cryptoctx, idopts, id_cryptoctx, getenv(residual)); break; case IDTYPE_FILE: retval = parse_fs_options(context, idopts, residual); break; case IDTYPE_PKCS12: retval = parse_pkcs12_options(context, idopts, residual); break; #ifndef WITHOUT_PKCS11 case IDTYPE_PKCS11: retval = parse_pkcs11_options(context, idopts, residual); break; #endif case IDTYPE_DIR: idopts->cert_filename = strdup(residual); if (idopts->cert_filename == NULL) retval = ENOMEM; break; default: krb5_set_error_message(context, KRB5_PREAUTH_FAILED, "Internal error parsing X509_user_identity\n"); retval = EINVAL; break; } return retval; }
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) { krb5_error_code retval = EINVAL; int i; pkiDebug("%s: %p %p %p\n", __FUNCTION__, context, idopts, id_cryptoctx); if (!(princ && krb5_principal_compare_any_realm (context, princ, krb5_anonymous_principal()))) { if (idopts == NULL || id_cryptoctx == NULL) goto errout; /* * If identity was specified, use that. (For the kdc, this * is specified as pkinit_identity in the kdc.conf. For users, * this is specified on the command line via X509_user_identity.) * If a user did not specify identity on the command line, * then we will try alternatives which may have been specified * in the config file. */ if (idopts->identity != NULL) { retval = process_option_identity(context, plg_cryptoctx, req_cryptoctx, idopts, id_cryptoctx, idopts->identity); } else if (idopts->identity_alt != NULL) { for (i = 0; retval != 0 && idopts->identity_alt[i] != NULL; i++) { retval = process_option_identity(context, plg_cryptoctx, req_cryptoctx, idopts, id_cryptoctx, idopts->identity_alt[i]); } } else { pkiDebug("%s: no user identity options specified\n", __FUNCTION__); goto errout; } if (retval) goto errout; retval = crypto_load_certs(context, plg_cryptoctx, req_cryptoctx, idopts, id_cryptoctx, princ); if (retval) goto errout; if (do_matching) { retval = pkinit_cert_matching(context, plg_cryptoctx, req_cryptoctx, id_cryptoctx, princ); if (retval) { pkiDebug("%s: No matching certificate found\n", __FUNCTION__); crypto_free_cert_info(context, plg_cryptoctx, req_cryptoctx, id_cryptoctx); goto errout; } } else { /* Tell crypto code to use the "default" */ retval = crypto_cert_select_default(context, plg_cryptoctx, req_cryptoctx, id_cryptoctx); if (retval) { pkiDebug("%s: Failed while selecting default certificate\n", __FUNCTION__); crypto_free_cert_info(context, plg_cryptoctx, req_cryptoctx, id_cryptoctx); goto errout; } } retval = crypto_free_cert_info(context, plg_cryptoctx, req_cryptoctx, id_cryptoctx); if (retval) goto errout; } /* Not anonymous principal */ for (i = 0; idopts->anchors != NULL && idopts->anchors[i] != NULL; i++) { retval = process_option_ca_crl(context, plg_cryptoctx, req_cryptoctx, idopts, id_cryptoctx, idopts->anchors[i], CATYPE_ANCHORS); if (retval) goto errout; } for (i = 0; idopts->intermediates != NULL && idopts->intermediates[i] != NULL; i++) { retval = process_option_ca_crl(context, plg_cryptoctx, req_cryptoctx, idopts, id_cryptoctx, idopts->intermediates[i], CATYPE_INTERMEDIATES); if (retval) goto errout; } for (i = 0; idopts->crls != NULL && idopts->crls[i] != NULL; i++) { retval = process_option_ca_crl(context, plg_cryptoctx, req_cryptoctx, idopts, id_cryptoctx, idopts->crls[i], CATYPE_CRLS); if (retval) goto errout; } if (idopts->ocsp != NULL) { retval = ENOTSUP; goto errout; } errout: return retval; }