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