diff options
Diffstat (limited to 'source4/heimdal/lib/krb5/pkinit.c')
-rwxr-xr-x | source4/heimdal/lib/krb5/pkinit.c | 157 |
1 files changed, 102 insertions, 55 deletions
diff --git a/source4/heimdal/lib/krb5/pkinit.c b/source4/heimdal/lib/krb5/pkinit.c index 00f7b4ebd9..f519b5ad08 100755 --- a/source4/heimdal/lib/krb5/pkinit.c +++ b/source4/heimdal/lib/krb5/pkinit.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: pkinit.c,v 1.99 2006/05/07 12:32:38 lha Exp $"); +RCSID("$Id: pkinit.c,v 1.110 2006/10/14 09:52:50 lha Exp $"); struct krb5_dh_moduli { char *name; @@ -69,7 +69,7 @@ struct krb5_pk_identity { hx509_certs certs; hx509_certs anchors; hx509_certs certpool; - hx509_revoke_ctx revoke; + hx509_revoke_ctx revokectx; }; struct krb5_pk_cert { @@ -344,8 +344,8 @@ build_auth_pack(krb5_context context, ALLOC(a->clientPublicValue, 1); if (a->clientPublicValue == NULL) return ENOMEM; - ret = copy_oid(oid_id_dhpublicnumber(), - &a->clientPublicValue->algorithm.algorithm); + ret = der_copy_oid(oid_id_dhpublicnumber(), + &a->clientPublicValue->algorithm.algorithm); if (ret) return ret; @@ -392,7 +392,7 @@ build_auth_pack(krb5_context context, ASN1_MALLOC_ENCODE(DHPublicKey, dhbuf.data, dhbuf.length, &dh_pub_key, &size, ret); - free_heim_integer(&dh_pub_key); + der_free_heim_integer(&dh_pub_key); if (ret) return ret; if (size != dhbuf.length) @@ -413,7 +413,7 @@ _krb5_pk_mk_ContentInfo(krb5_context context, { krb5_error_code ret; - ret = copy_oid(oid, &content_info->contentType); + ret = der_copy_oid(oid, &content_info->contentType); if (ret) return ret; ALLOC(content_info->content, 1); @@ -672,8 +672,16 @@ _krb5_pk_verify_sign(krb5_context context, contentType, content, &signer_certs); - if (ret) + if (ret) { + char *s = hx509_get_error_string(id->hx509ctx, ret); + if (s) { + krb5_set_error_string(context, + "CMS verify signed failed with %s", s); + free(s); + } else + krb5_clear_error_string(context); return ret; + } *signer = calloc(1, sizeof(**signer)); if (*signer == NULL) { @@ -833,7 +841,9 @@ pk_verify_host(krb5_context context, oid_id_pkinit_san(), &list); if (ret) { - krb5_clear_error_string(context); + krb5_set_error_string(context, "Failed to find the PK-INIT " + "subjectAltName in the KDC certificate"); + return ret; } @@ -845,7 +855,9 @@ pk_verify_host(krb5_context context, &r, NULL); if (ret) { - krb5_clear_error_string(context); + krb5_set_error_string(context, "Failed to decode the PK-INIT " + "subjectAltName in the KDC certificate"); + break; } @@ -856,7 +868,7 @@ pk_verify_host(krb5_context context, { krb5_set_error_string(context, "KDC have wrong realm name in " "the certificate"); - ret = EINVAL; + ret = KRB5_KDC_ERR_INVALID_CERTIFICATE; } free_KRB5PrincipalName(&r); @@ -875,7 +887,8 @@ pk_verify_host(krb5_context context, hi->ai->ai_addr, hi->ai->ai_addrlen); if (ret) - krb5_set_error_string(context, "Address mismatch in the KDC certificate"); + krb5_set_error_string(context, "Address mismatch in " + "the KDC certificate"); } return ret; } @@ -901,7 +914,7 @@ pk_rd_pa_reply_enckey(krb5_context context, krb5_data content; heim_oid contentType = { 0, NULL }; - if (heim_oid_cmp(oid_id_pkcs7_envelopedData(), &rep->contentType)) { + if (der_heim_oid_cmp(oid_id_pkcs7_envelopedData(), &rep->contentType)) { krb5_set_error_string(context, "PKINIT: Invalid content type"); return EINVAL; } @@ -913,8 +926,10 @@ pk_rd_pa_reply_enckey(krb5_context context, ret = hx509_cms_unenvelope(ctx->id->hx509ctx, ctx->id->certs, + HX509_CMS_UE_DONT_REQUIRE_KU_ENCIPHERMENT, rep->content->data, rep->content->length, + NULL, &contentType, &content); if (ret) @@ -935,7 +950,7 @@ pk_rd_pa_reply_enckey(krb5_context context, goto out; } - if (heim_oid_cmp(&ci.contentType, oid_id_pkcs7_signedData())) { + if (der_heim_oid_cmp(&ci.contentType, oid_id_pkcs7_signedData())) { ret = EINVAL; /* XXX */ krb5_set_error_string(context, "PKINIT: Invalid content type"); goto out; @@ -964,19 +979,18 @@ pk_rd_pa_reply_enckey(krb5_context context, /* make sure that it is the kdc's certificate */ ret = pk_verify_host(context, realm, hi, ctx, host); if (ret) { - krb5_set_error_string(context, "PKINIT: failed verify host: %d", ret); goto out; } #if 0 if (type == COMPAT_WIN2K) { - if (heim_oid_cmp(&contentType, oid_id_pkcs7_data()) != 0) { + if (der_heim_oid_cmp(&contentType, oid_id_pkcs7_data()) != 0) { krb5_set_error_string(context, "PKINIT: reply key, wrong oid"); ret = KRB5KRB_AP_ERR_MSG_TYPE; goto out; } } else { - if (heim_oid_cmp(&contentType, oid_id_pkrkeydata()) != 0) { + if (der_heim_oid_cmp(&contentType, oid_id_pkrkeydata()) != 0) { krb5_set_error_string(context, "PKINIT: reply key, wrong oid"); ret = KRB5KRB_AP_ERR_MSG_TYPE; goto out; @@ -1002,7 +1016,7 @@ pk_rd_pa_reply_enckey(krb5_context context, out: if (host) _krb5_pk_cert_free(host); - free_oid(&contentType); + der_free_oid(&contentType); krb5_data_free(&content); return ret; @@ -1034,7 +1048,7 @@ pk_rd_pa_reply_dh(krb5_context context, krb5_data_zero(&content); memset(&kdc_dh_info, 0, sizeof(kdc_dh_info)); - if (heim_oid_cmp(oid_id_pkcs7_signedData(), &rep->contentType)) { + if (der_heim_oid_cmp(oid_id_pkcs7_signedData(), &rep->contentType)) { krb5_set_error_string(context, "PKINIT: Invalid content type"); return EINVAL; } @@ -1059,7 +1073,7 @@ pk_rd_pa_reply_dh(krb5_context context, if (ret) goto out; - if (heim_oid_cmp(&contentType, oid_id_pkdhkeydata())) { + if (der_heim_oid_cmp(&contentType, oid_id_pkdhkeydata())) { krb5_set_error_string(context, "pkinit - dh reply contains wrong oid"); ret = KRB5KRB_AP_ERR_MSG_TYPE; goto out; @@ -1324,20 +1338,28 @@ hx_pass_prompter(void *data, const hx509_prompt *prompter) password_data.data = prompter->reply.data; password_data.length = prompter->reply.length; - prompt.prompt = "Enter your private key passphrase: "; - prompt.hidden = 1; + + prompt.prompt = prompter->prompt; + prompt.hidden = hx509_prompt_hidden(prompter->type); prompt.reply = &password_data; - if (prompter->hidden) + + switch (prompter->type) { + case HX509_PROMPT_TYPE_INFO: + prompt.type = KRB5_PROMPT_TYPE_INFO; + break; + case HX509_PROMPT_TYPE_PASSWORD: + case HX509_PROMPT_TYPE_QUESTION: + default: prompt.type = KRB5_PROMPT_TYPE_PASSWORD; - else - prompt.type = KRB5_PROMPT_TYPE_PREAUTH; /* XXX */ + break; + } ret = (*p->prompter)(p->context, p->prompter_data, NULL, NULL, 1, &prompt); if (ret) { memset (prompter->reply.data, 0, prompter->reply.length); - return 0; + return 1; } - return strlen(prompter->reply.data); + return 0; } @@ -1354,8 +1376,8 @@ _krb5_pk_load_id(krb5_context context, struct krb5_pk_identity **ret_id, const char *user_id, const char *anchor_id, - char * const *chain, - char * const *revoke, + char * const *chain_list, + char * const *revoke_list, krb5_prompter_fct prompter, void *prompter_data, char *password) @@ -1392,7 +1414,7 @@ _krb5_pk_load_id(krb5_context context, goto out; ret = hx509_lock_init(id->hx509ctx, &lock); - if (password) + if (password && password[0]) hx509_lock_add_password(lock, password); if (prompter) { @@ -1405,7 +1427,7 @@ _krb5_pk_load_id(krb5_context context, goto out; } - ret = hx509_certs_init(id->hx509ctx, user_id, 0, NULL, &id->certs); + ret = hx509_certs_init(id->hx509ctx, user_id, 0, lock, &id->certs); if (ret) goto out; @@ -1418,33 +1440,36 @@ _krb5_pk_load_id(krb5_context context, if (ret) goto out; - while (chain && *chain) { - ret = hx509_certs_append(id->hx509ctx, id->certpool, NULL, *chain); + while (chain_list && *chain_list) { + ret = hx509_certs_append(id->hx509ctx, id->certpool, + NULL, *chain_list); if (ret) { krb5_set_error_string(context, "pkinit failed to load chain %s", - *chain); + *chain_list); goto out; } - chain++; + chain_list++; } - if (revoke) { - ret = hx509_revoke_init(id->hx509ctx, &id->revoke); + if (revoke_list) { + ret = hx509_revoke_init(id->hx509ctx, &id->revokectx); if (ret) { krb5_set_error_string(context, "revoke failed to init"); goto out; } - while (*revoke) { - ret = hx509_revoke_add_crl(id->hx509ctx, id->revoke, *revoke); + while (*revoke_list) { + ret = hx509_revoke_add_crl(id->hx509ctx, + id->revokectx, + *revoke_list); if (ret) { krb5_set_error_string(context, "pkinit failed to load revoke %s", - *revoke); + *revoke_list); goto out; } - revoke++; + revoke_list++; } } else hx509_context_set_missing_revoke(id->hx509ctx, 1); @@ -1454,7 +1479,7 @@ _krb5_pk_load_id(krb5_context context, goto out; hx509_verify_attach_anchors(id->verify_ctx, id->anchors); - hx509_verify_attach_revoke(id->verify_ctx, id->revoke); + hx509_verify_attach_revoke(id->verify_ctx, id->revokectx); out: if (ret) { @@ -1462,7 +1487,7 @@ out: hx509_certs_free(&id->certs); hx509_certs_free(&id->anchors); hx509_certs_free(&id->certpool); - hx509_revoke_free(&id->revoke); + hx509_revoke_free(&id->revokectx); hx509_context_free(&id->hx509ctx); free(id); } else @@ -1588,9 +1613,9 @@ _krb5_parse_moduli_line(krb5_context context, return 0; out: free(m1->name); - free_heim_integer(&m1->p); - free_heim_integer(&m1->g); - free_heim_integer(&m1->q); + der_free_heim_integer(&m1->p); + der_free_heim_integer(&m1->g); + der_free_heim_integer(&m1->q); free(m1); return ret; } @@ -1601,9 +1626,9 @@ _krb5_free_moduli(struct krb5_dh_moduli **moduli) int i; for (i = 0; moduli[i] != NULL; i++) { free(moduli[i]->name); - free_heim_integer(&moduli[i]->p); - free_heim_integer(&moduli[i]->g); - free_heim_integer(&moduli[i]->q); + der_free_heim_integer(&moduli[i]->p); + der_free_heim_integer(&moduli[i]->g); + der_free_heim_integer(&moduli[i]->q); free(moduli[i]); } free(moduli); @@ -1712,9 +1737,9 @@ _krb5_dh_group_ok(krb5_context context, unsigned long bits, *name = NULL; for (i = 0; moduli[i] != NULL; i++) { - if (heim_integer_cmp(&moduli[i]->g, g) == 0 && - heim_integer_cmp(&moduli[i]->p, p) == 0 && - (q == NULL || heim_integer_cmp(&moduli[i]->q, q) == 0)) + if (der_heim_integer_cmp(&moduli[i]->g, g) == 0 && + der_heim_integer_cmp(&moduli[i]->p, p) == 0 && + (q == NULL || der_heim_integer_cmp(&moduli[i]->q, q) == 0)) { if (bits && bits > moduli[i]->bits) { krb5_set_error_string(context, "PKINIT: DH group parameter %s " @@ -1769,8 +1794,8 @@ krb5_get_init_creds_opt_set_pkinit(krb5_context context, krb5_principal principal, const char *user_id, const char *x509_anchors, - char * const * chain, - char * const * revoke, + char * const * pool, + char * const * pki_revoke, int flags, krb5_prompter_fct prompter, void *prompter_data, @@ -1778,6 +1803,7 @@ krb5_get_init_creds_opt_set_pkinit(krb5_context context, { #ifdef PKINIT krb5_error_code ret; + char *anchors = NULL; if (opt->opt_private == NULL) { krb5_set_error_string(context, "PKINIT: on non extendable opt"); @@ -1797,12 +1823,33 @@ krb5_get_init_creds_opt_set_pkinit(krb5_context context, opt->opt_private->pk_init_ctx->require_eku = 1; opt->opt_private->pk_init_ctx->require_krbtgt_otherName = 1; + + /* XXX implement krb5_appdefault_strings */ + if (pool == NULL) + pool = krb5_config_get_strings(context, NULL, + "appdefaults", + "pkinit-pool", + NULL); + + if (pki_revoke == NULL) + pki_revoke = krb5_config_get_strings(context, NULL, + "appdefaults", + "pkinit-revoke", + NULL); + + if (x509_anchors == NULL) { + krb5_appdefault_string(context, "kinit", + krb5_principal_get_realm(context, principal), + "pkinit-anchors", NULL, &anchors); + x509_anchors = anchors; + } + ret = _krb5_pk_load_id(context, &opt->opt_private->pk_init_ctx->id, user_id, x509_anchors, - chain, - revoke, + pool, + pki_revoke, prompter, prompter_data, password); |