Inline short functions, share more code, rename COMPAT_27 to

COMPAT_IETF, pass down a krb5_krbhst_info for verification of KDC
info, and general cleaning up.


git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@16151 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
Love Hörnquist Åstrand
2005-10-08 15:32:14 +00:00
parent be13646074
commit 6b484c39a5

View File

@@ -57,7 +57,7 @@ RCSID("$Id$");
enum { enum {
COMPAT_WIN2K = 1, COMPAT_WIN2K = 1,
COMPAT_27 = 3 COMPAT_IETF = 2
}; };
#define OPENSSL_ASN1_MALLOC_ENCODE(T, B, BL, S, R) \ #define OPENSSL_ASN1_MALLOC_ENCODE(T, B, BL, S, R) \
@@ -119,7 +119,6 @@ struct krb5_pk_init_ctx_data {
struct krb5_dh_moduli **m; struct krb5_dh_moduli **m;
}; };
void KRB5_LIB_FUNCTION void KRB5_LIB_FUNCTION
_krb5_pk_cert_free(struct krb5_pk_cert *cert) _krb5_pk_cert_free(struct krb5_pk_cert *cert)
{ {
@@ -465,32 +464,6 @@ _krb5_pk_create_sign(krb5_context context,
return ret; return ret;
} }
static krb5_error_code
build_auth_pack_win2k(krb5_context context,
unsigned nonce,
const KDC_REQ_BODY *body,
AuthPack_Win2k *a)
{
krb5_error_code ret;
krb5_timestamp sec;
int32_t usec;
/* fill in PKAuthenticator */
ret = copy_PrincipalName(body->sname, &a->pkAuthenticator.kdcName);
if (ret)
return ret;
ret = copy_Realm(&body->realm, &a->pkAuthenticator.kdcRealm);
if (ret)
return ret;
krb5_us_timeofday(context, &sec, &usec);
a->pkAuthenticator.ctime = sec;
a->pkAuthenticator.cusec = usec;
a->pkAuthenticator.nonce = nonce;
return 0;
}
static krb5_error_code static krb5_error_code
build_auth_pack(krb5_context context, build_auth_pack(krb5_context context,
unsigned nonce, unsigned nonce,
@@ -528,13 +501,16 @@ build_auth_pack(krb5_context context,
len, len,
&checksum); &checksum);
free(buf); free(buf);
if (ret == 0) { if (ret)
ret = krb5_data_copy(&a->pkAuthenticator.paChecksum, return ret;
checksum.checksum.data, checksum.checksum.length);
free_Checksum(&checksum);
}
if (ret == 0 && dh) { ret = krb5_data_copy(&a->pkAuthenticator.paChecksum,
checksum.checksum.data, checksum.checksum.length);
free_Checksum(&checksum);
if (ret)
return ret;
if (dh) {
DomainParameters dp; DomainParameters dp;
heim_integer dh_pub_key; heim_integer dh_pub_key;
krb5_data dhbuf; krb5_data dhbuf;
@@ -655,26 +631,39 @@ pk_mk_padata(krb5_context context,
struct ContentInfo content_info; struct ContentInfo content_info;
krb5_error_code ret; krb5_error_code ret;
const heim_oid *oid; const heim_oid *oid;
PA_PK_AS_REQ req;
size_t size; size_t size;
krb5_data buf, sd_buf; krb5_data buf, sd_buf;
int pa_type; int pa_type;
krb5_data_zero(&buf); krb5_data_zero(&buf);
krb5_data_zero(&sd_buf); krb5_data_zero(&sd_buf);
memset(&req, 0, sizeof(req));
memset(&content_info, 0, sizeof(content_info)); memset(&content_info, 0, sizeof(content_info));
if (compat == COMPAT_WIN2K) { if (compat == COMPAT_WIN2K) {
AuthPack_Win2k ap; AuthPack_Win2k ap;
krb5_timestamp sec;
int32_t usec;
memset(&ap, 0, sizeof(ap)); memset(&ap, 0, sizeof(ap));
ret = build_auth_pack_win2k(context, nonce, req_body, &ap); /* fill in PKAuthenticator */
ret = copy_PrincipalName(req_body->sname, &ap.pkAuthenticator.kdcName);
if (ret) { if (ret) {
free_AuthPack_Win2k(&ap); free_AuthPack_Win2k(&ap);
krb5_clear_error_string(context);
goto out; goto out;
} }
ret = copy_Realm(&req_body->realm, &ap.pkAuthenticator.kdcRealm);
if (ret) {
free_AuthPack_Win2k(&ap);
krb5_clear_error_string(context);
goto out;
}
krb5_us_timeofday(context, &sec, &usec);
ap.pkAuthenticator.ctime = sec;
ap.pkAuthenticator.cusec = usec;
ap.pkAuthenticator.nonce = nonce;
ASN1_MALLOC_ENCODE(AuthPack_Win2k, buf.data, buf.length, ASN1_MALLOC_ENCODE(AuthPack_Win2k, buf.data, buf.length,
&ap, &size, ret); &ap, &size, ret);
@@ -687,7 +676,7 @@ pk_mk_padata(krb5_context context,
krb5_abortx(context, "internal ASN1 encoder error"); krb5_abortx(context, "internal ASN1 encoder error");
oid = oid_id_pkcs7_data(); oid = oid_id_pkcs7_data();
} else if (compat == COMPAT_27) { } else if (compat == COMPAT_IETF) {
AuthPack ap; AuthPack ap;
memset(&ap, 0, sizeof(ap)); memset(&ap, 0, sizeof(ap));
@@ -726,9 +715,12 @@ pk_mk_padata(krb5_context context,
if (ret) if (ret)
goto out; goto out;
/* XXX tell the kdc what CAs the client is willing to accept */ ASN1_MALLOC_ENCODE(ContentInfo, buf.data, buf.length,
req.trustedCertifiers = NULL; &content_info, &size, ret);
req.kdcPkId = NULL; if (ret)
goto out;
if (buf.length != size)
krb5_abortx(context, "Internal ASN1 encoder error");
if (compat == COMPAT_WIN2K) { if (compat == COMPAT_WIN2K) {
PA_PK_AS_REQ_Win2k winreq; PA_PK_AS_REQ_Win2k winreq;
@@ -737,39 +729,29 @@ pk_mk_padata(krb5_context context,
memset(&winreq, 0, sizeof(winreq)); memset(&winreq, 0, sizeof(winreq));
ASN1_MALLOC_ENCODE(ContentInfo, winreq.signed_auth_pack = buf;
winreq.signed_auth_pack.data,
winreq.signed_auth_pack.length,
&content_info,
&size,
ret);
if (ret)
goto out;
if (winreq.signed_auth_pack.length != size)
krb5_abortx(context, "Internal ASN1 encoder error");
ASN1_MALLOC_ENCODE(PA_PK_AS_REQ_Win2k, buf.data, buf.length, ASN1_MALLOC_ENCODE(PA_PK_AS_REQ_Win2k, buf.data, buf.length,
&winreq, &size, ret); &winreq, &size, ret);
free_PA_PK_AS_REQ_Win2k(&winreq); free_PA_PK_AS_REQ_Win2k(&winreq);
} else if (compat == COMPAT_27) { } else if (compat == COMPAT_IETF) {
PA_PK_AS_REQ req;
pa_type = KRB5_PADATA_PK_AS_REQ; pa_type = KRB5_PADATA_PK_AS_REQ;
ASN1_MALLOC_ENCODE(ContentInfo, memset(&req, 0, sizeof(req));
req.signedAuthPack.data, req.signedAuthPack = buf;
req.signedAuthPack.length,
&content_info, /* XXX tell the kdc what CAs the client is willing to accept */
&size, req.trustedCertifiers = NULL;
ret); req.kdcPkId = NULL;
if (ret)
goto out;
if (req.signedAuthPack.length != size)
krb5_abortx(context, "Internal ASN1 encoder error");
ASN1_MALLOC_ENCODE(PA_PK_AS_REQ, buf.data, buf.length, ASN1_MALLOC_ENCODE(PA_PK_AS_REQ, buf.data, buf.length,
&req, &size, ret); &req, &size, ret);
free_PA_PK_AS_REQ(&req);
} else } else
krb5_abortx(context, "internal pkinit error"); krb5_abortx(context, "internal pkinit error");
if (ret) { if (ret) {
@@ -782,7 +764,7 @@ pk_mk_padata(krb5_context context,
ret = krb5_padata_add(context, md, pa_type, buf.data, buf.length); ret = krb5_padata_add(context, md, pa_type, buf.data, buf.length);
if (ret) if (ret)
free(buf.data); free(buf.data);
out: out:
free_ContentInfo(&content_info); free_ContentInfo(&content_info);
return ret; return ret;
@@ -814,7 +796,7 @@ _krb5_pk_mk_padata(krb5_context context,
if (ret) if (ret)
goto out; goto out;
} else { } else {
ret = pk_mk_padata(context, COMPAT_27, ctx, req_body, nonce, md); ret = pk_mk_padata(context, COMPAT_IETF, ctx, req_body, nonce, md);
if (ret) if (ret)
goto out; goto out;
} }
@@ -1318,6 +1300,7 @@ pk_rd_pa_reply_enckey(krb5_context context,
ContentInfo *rep, ContentInfo *rep,
krb5_pk_init_ctx ctx, krb5_pk_init_ctx ctx,
krb5_enctype etype, krb5_enctype etype,
const krb5_krbhst_info *hi,
unsigned nonce, unsigned nonce,
const krb5_data *req_buffer, const krb5_data *req_buffer,
PA_DATA *pa, PA_DATA *pa,
@@ -1521,7 +1504,7 @@ pk_rd_pa_reply_enckey(krb5_context context,
case COMPAT_WIN2K: case COMPAT_WIN2K:
ret = get_reply_key_win(context, &content, nonce, key); ret = get_reply_key_win(context, &content, nonce, key);
break; break;
case COMPAT_27: case COMPAT_IETF:
ret = get_reply_key(context, &content, req_buffer, key); ret = get_reply_key(context, &content, req_buffer, key);
break; break;
} }
@@ -1548,6 +1531,7 @@ pk_rd_pa_reply_dh(krb5_context context,
ContentInfo *rep, ContentInfo *rep,
krb5_pk_init_ctx ctx, krb5_pk_init_ctx ctx,
krb5_enctype etype, krb5_enctype etype,
const krb5_krbhst_info *hi,
const DHNonce *c_n, const DHNonce *c_n,
const DHNonce *k_n, const DHNonce *k_n,
unsigned nonce, unsigned nonce,
@@ -1593,12 +1577,11 @@ pk_rd_pa_reply_dh(krb5_context context,
if (ret) if (ret)
goto out; goto out;
#if 0
if (heim_oid_cmp(&contentType, oid_id_pkdhkeydata())) { if (heim_oid_cmp(&contentType, oid_id_pkdhkeydata())) {
ret = KRB5KRB_AP_ERR_MSG_TYPE; /* XXX */ krb5_set_error_string(context, "pkinit - dh reply contains wrong oid");
ret = KRB5KRB_AP_ERR_MSG_TYPE;
goto out; goto out;
} }
#endif
ret = decode_KDCDHKeyInfo(content.data, ret = decode_KDCDHKeyInfo(content.data,
content.length, content.length,
@@ -1721,6 +1704,7 @@ krb5_error_code KRB5_LIB_FUNCTION
_krb5_pk_rd_pa_reply(krb5_context context, _krb5_pk_rd_pa_reply(krb5_context context,
void *c, void *c,
krb5_enctype etype, krb5_enctype etype,
const krb5_krbhst_info *hi,
unsigned nonce, unsigned nonce,
const krb5_data *req_buffer, const krb5_data *req_buffer,
PA_DATA *pa, PA_DATA *pa,
@@ -1758,7 +1742,7 @@ _krb5_pk_rd_pa_reply(krb5_context context,
free_PA_PK_AS_REP(&rep); free_PA_PK_AS_REP(&rep);
break; break;
} }
ret = pk_rd_pa_reply_dh(context, &ci, ctx, etype, ret = pk_rd_pa_reply_dh(context, &ci, ctx, etype, hi,
ctx->clientDHNonce, ctx->clientDHNonce,
rep.u.dhInfo.serverDHNonce, rep.u.dhInfo.serverDHNonce,
nonce, pa, key); nonce, pa, key);
@@ -1778,8 +1762,8 @@ _krb5_pk_rd_pa_reply(krb5_context context,
"ContentInfo: %d", ret); "ContentInfo: %d", ret);
break; break;
} }
ret = pk_rd_pa_reply_enckey(context, COMPAT_27, &ci, ctx, ret = pk_rd_pa_reply_enckey(context, COMPAT_IETF, &ci, ctx,
etype, nonce, req_buffer, pa, key); etype, hi, nonce, req_buffer, pa, key);
free_ContentInfo(&ci); free_ContentInfo(&ci);
return ret; return ret;
default: default:
@@ -1826,7 +1810,7 @@ _krb5_pk_rd_pa_reply(krb5_context context,
return ret; return ret;
} }
ret = pk_rd_pa_reply_enckey(context, COMPAT_WIN2K, &ci, ctx, ret = pk_rd_pa_reply_enckey(context, COMPAT_WIN2K, &ci, ctx,
etype, nonce, NULL, pa, key); etype, hi, nonce, NULL, pa, key);
free_ContentInfo(&ci); free_ContentInfo(&ci);
break; break;
default: default:
@@ -2450,16 +2434,12 @@ parse_integer(krb5_context context, char **p, const char *file, int lineno,
file, name, lineno); file, name, lineno);
return EINVAL; return EINVAL;
} }
if (strcmp(p1, "-") == 0) { ret = der_parse_hex_heim_integer(p1, integer);
memset(integer, 0, sizeof(*integer)); if (ret) {
} else { krb5_set_error_string(context, "moduli file %s failed parsing %s "
ret = der_parse_hex_heim_integer(p1, integer); "on line %d",
if (ret) { file, name, lineno);
krb5_set_error_string(context, "moduli file %s failed parsing %s " return ret;
"on line %d",
file, name, lineno);
return ret;
}
} }
return 0; return 0;
@@ -2608,8 +2588,10 @@ _krb5_parse_moduli(krb5_context context, const char *file,
} }
f = fopen(file, "r"); f = fopen(file, "r");
if (f == NULL) if (f == NULL) {
*moduli = m;
return 0; return 0;
}
while(fgets(buf, sizeof(buf), f) != NULL) { while(fgets(buf, sizeof(buf), f) != NULL) {
struct krb5_dh_moduli *element; struct krb5_dh_moduli *element;
@@ -2653,7 +2635,7 @@ _krb5_dh_group_ok(krb5_context context, unsigned long bits,
for (i = 0; moduli[i] != NULL; i++) { for (i = 0; moduli[i] != NULL; i++) {
if (heim_integer_cmp(&moduli[i]->g, g) == 0 && if (heim_integer_cmp(&moduli[i]->g, g) == 0 &&
heim_integer_cmp(&moduli[i]->p, p) == 0 && heim_integer_cmp(&moduli[i]->p, p) == 0 &&
(moduli[i]->q.length == 0 || heim_integer_cmp(&moduli[i]->q, q) == 0)) heim_integer_cmp(&moduli[i]->q, q) == 0)
{ {
if (name) if (name)
*name = strdup(moduli[i]->name); *name = strdup(moduli[i]->name);
@@ -2677,10 +2659,10 @@ select_dh_group(krb5_context context, DH *dh, unsigned long bits,
dh->p = integer_to_BN(context, "p", &m->p); dh->p = integer_to_BN(context, "p", &m->p);
if (dh->p == NULL) if (dh->p == NULL)
return ENOMEM; return ENOMEM;
dh->g = integer_to_BN(context, "p", &m->g); dh->g = integer_to_BN(context, "g", &m->g);
if (dh->g == NULL) if (dh->g == NULL)
return ENOMEM; return ENOMEM;
dh->q = integer_to_BN(context, "p", &m->q); dh->q = integer_to_BN(context, "q", &m->q);
if (dh->q == NULL) if (dh->q == NULL)
return ENOMEM; return ENOMEM;
@@ -2767,20 +2749,14 @@ krb5_get_init_creds_opt_set_pkinit(krb5_context context,
return ret; return ret;
} }
if (1) { if ((flags & 2) == 0) {
const char *moduli_file; const char *moduli_file;
DH *dh;
dh = DH_new(); moduli_file = krb5_config_get_string_default(context, NULL,
if (dh == NULL) { MODULI_FILE,
krb5_set_error_string(context, "malloc: out of memory"); "libdefaults",
_krb5_get_init_creds_opt_free_pkinit(opt); "moduli",
return ENOMEM; NULL);
}
opt->private->pk_init_ctx->dh = dh;
moduli_file = krb5_config_get_string(context, NULL,
"libdefaults", "moduli", NULL);
ret = _krb5_parse_moduli(context, moduli_file, ret = _krb5_parse_moduli(context, moduli_file,
&opt->private->pk_init_ctx->m); &opt->private->pk_init_ctx->m);
@@ -2789,14 +2765,21 @@ krb5_get_init_creds_opt_set_pkinit(krb5_context context,
return ret; return ret;
} }
ret = select_dh_group(context, dh, 0, opt->private->pk_init_ctx->m); opt->private->pk_init_ctx->dh = DH_new();
if (opt->private->pk_init_ctx->dh == NULL) {
krb5_set_error_string(context, "malloc: out of memory");
_krb5_get_init_creds_opt_free_pkinit(opt);
return ENOMEM;
}
ret = select_dh_group(context, opt->private->pk_init_ctx->dh, 0,
opt->private->pk_init_ctx->m);
if (ret) { if (ret) {
_krb5_get_init_creds_opt_free_pkinit(opt); _krb5_get_init_creds_opt_free_pkinit(opt);
return ret; return ret;
} }
/* XXX generate a new key for each request ? */ if (DH_generate_key(opt->private->pk_init_ctx->dh) != 1) {
if (DH_generate_key(dh) != 1) {
krb5_set_error_string(context, "malloc: out of memory"); krb5_set_error_string(context, "malloc: out of memory");
_krb5_get_init_creds_opt_free_pkinit(opt); _krb5_get_init_creds_opt_free_pkinit(opt);
return ENOMEM; return ENOMEM;