diff --git a/kdc/config.c b/kdc/config.c index e13e85bea..4f9623feb 100644 --- a/kdc/config.c +++ b/kdc/config.c @@ -501,7 +501,8 @@ configure(krb5_context context, int argc, char **argv) "enable-pkinit", NULL); if (config->enable_pkinit) { - const char *user_id, *x509_anchors; + const char *user_id, *anchors; + char **chain; user_id = krb5_config_get_string(context, NULL, "kdc", @@ -510,14 +511,21 @@ configure(krb5_context context, int argc, char **argv) if (user_id == NULL) krb5_errx(context, 1, "pkinit enabled but no identity"); - x509_anchors = krb5_config_get_string(context, NULL, - "kdc", - "pki-anchors", - NULL); - if (x509_anchors == NULL) + anchors = krb5_config_get_string(context, NULL, + "kdc", + "pki-anchors", + NULL); + if (anchors == NULL) krb5_errx(context, 1, "pkinit enabled but no X509 anchors"); - _kdc_pk_initialize(context, config, user_id, x509_anchors); + chain = krb5_config_get_strings(context, NULL, + "kdc", + "pki-chain", + NULL); + + _kdc_pk_initialize(context, config, user_id, anchors, chain); + + krb5_config_free_strings(chain); config->enable_pkinit_princ_in_cert = krb5_config_get_bool_default(context, diff --git a/kdc/pkinit.c b/kdc/pkinit.c index e1ec960a3..564237804 100644 --- a/kdc/pkinit.c +++ b/kdc/pkinit.c @@ -51,6 +51,7 @@ struct krb5_pk_identity { hx509_verify_ctx verify_ctx; hx509_certs certs; hx509_certs anchors; + hx509_certs chain; }; enum pkinit_type { @@ -1233,7 +1234,8 @@ krb5_error_code _kdc_pk_initialize(krb5_context context, krb5_kdc_configuration *config, const char *user_id, - const char *x509_anchors) + const char *anchors, + char **chain) { const char *file; krb5_error_code ret; @@ -1254,7 +1256,8 @@ _kdc_pk_initialize(krb5_context context, ret = _krb5_pk_load_openssl_id(context, &kdc_identity, user_id, - x509_anchors, + anchors, + chain, NULL, NULL, NULL); diff --git a/lib/krb5/pkinit.c b/lib/krb5/pkinit.c index e9379c088..dc7fbfc75 100644 --- a/lib/krb5/pkinit.c +++ b/lib/krb5/pkinit.c @@ -68,6 +68,7 @@ struct krb5_pk_identity { hx509_verify_ctx verify_ctx; hx509_certs certs; hx509_certs anchors; + hx509_certs chain; }; struct krb5_pk_cert { @@ -1147,6 +1148,7 @@ _krb5_pk_load_openssl_id(krb5_context context, struct krb5_pk_identity **ret_id, const char *user_id, const char *anchor_id, + const char **chain, krb5_prompter_fct prompter, void *prompter_data, char *password) @@ -1204,6 +1206,22 @@ _krb5_pk_load_openssl_id(krb5_context context, if (ret) goto out; + ret = hx509_certs_init(id->hx509ctx, "MEMORY:pkinit-cert-chain", + 0, NULL, &id->chain); + if (ret) + goto out; + + while (chain && *chain) { + ret = hx509_certs_append(id->hx509ctx, id->chain, NULL, *chain); + if (ret) { + krb5_set_error_string(context, + "pkinit failed to load chain %s", + *chain); + goto out; + } + chain++; + } + ret = hx509_verify_init_ctx(id->hx509ctx, &id->verify_ctx); if (ret) goto out; @@ -1215,6 +1233,7 @@ out: hx509_verify_destroy_ctx(id->verify_ctx); hx509_certs_free(&id->certs); hx509_certs_free(&id->anchors); + hx509_certs_free(&id->chain); hx509_context_free(&id->hx509ctx); free(id); } else @@ -1499,6 +1518,7 @@ _krb5_get_init_creds_opt_free_pkinit(krb5_get_init_creds_opt *opt) hx509_verify_destroy_ctx(ctx->id->verify_ctx); hx509_certs_free(&ctx->id->certs); hx509_certs_free(&ctx->id->anchors); + hx509_certs_free(&ctx->id->chain); hx509_context_free(&ctx->id->hx509ctx); if (ctx->clientDHNonce) { @@ -1548,6 +1568,7 @@ krb5_get_init_creds_opt_set_pkinit(krb5_context context, &opt->opt_private->pk_init_ctx->id, user_id, x509_anchors, + NULL, prompter, prompter_data, password);